コード例 #1
0
    def check(self, content, use_emb_key=False, skip_nonce_check=False):
        """ validate message """
        self.logger.debug('Message.check()')
        # disable signature check if paramter has been set
        if self.disable_dic['signature_check_disable']:
            self.logger.error(
                '**** SIGNATURE_CHECK_DISABLE!!! Severe security issue ****')
            skip_signature_check = True
        else:
            skip_signature_check = False

        # decode message
        (result, error_detail, protected, payload,
         _signature) = decode_message(self.logger, content)
        account_name = None
        if result:
            # decoding successful - check nonce for anti replay protection
            if skip_nonce_check or self.disable_dic['nonce_check_disable']:
                # nonce check can be skipped by configuration and in case of key-rollover
                if self.disable_dic['nonce_check_disable']:
                    self.logger.error(
                        '**** NONCE CHECK DISABLED!!! Severe security issue ****'
                    )
                else:
                    self.logger.debug(
                        'skip nonce check of inner payload during keyrollover')
                code = 200
                message = None
                detail = None
            else:
                (code, message, detail) = self.nonce.check(protected)

            if code == 200 and not skip_signature_check:
                # nonce check successful - check signature
                account_name = self._name_get(protected)
                signature = Signature(self.debug, self.server_name,
                                      self.logger)
                # we need the decoded protected header to grab a key to verify signature
                (sig_check, error,
                 error_detail) = signature.check(account_name, content,
                                                 use_emb_key, protected)
                if sig_check:
                    code = 200
                    message = None
                    detail = None
                else:
                    code = 403
                    message = error
                    detail = error_detail
        else:
            # message could not get decoded
            code = 400
            message = 'urn:ietf:params:acme:error:malformed'
            detail = error_detail

        self.logger.debug('Message.check() ended with:{0}'.format(code))
        return (code, message, detail, protected, payload, account_name)
コード例 #2
0
 def setUp(self):
     """ setup unittest """
     models_mock = MagicMock()
     models_mock.acme.db_handler.DBstore.return_value = FakeDBStore
     modules = {'acme.db_handler': models_mock}
     patch.dict('sys.modules', modules).start()
     import logging
     logging.basicConfig(level=logging.CRITICAL)
     self.logger = logging.getLogger('test_a2c')
     from acme.signature import Signature
     self.signature = Signature(False, 'http://tester.local', self.logger)
コード例 #3
0
    def _eab_signature_verify(self, content, mac_key):
        """ verify inner signature """
        self.logger.debug('Account._eab_signature_verify()')

        if content and mac_key:
            signature = Signature(None, self.server_name, self.logger)
            jwk_ = json.dumps({'k': mac_key, 'kty': 'oct'})
            (sig_check, error) = signature.eab_check(json.dumps(content), jwk_)
        else:
            sig_check = False
            error = None
        self.logger.debug(
            'Account._eab_signature_verify() ended with: {0}'.format(
                sig_check))
        return (sig_check, error)
コード例 #4
0
class TestACMEHandler(unittest.TestCase):
    """ test class for ACMEHandler """
    acme = None

    def setUp(self):
        """ setup unittest """
        models_mock = MagicMock()
        models_mock.acme.db_handler.DBstore.return_value = FakeDBStore
        modules = {'acme.db_handler': models_mock}
        patch.dict('sys.modules', modules).start()
        import logging
        logging.basicConfig(level=logging.CRITICAL)
        self.logger = logging.getLogger('test_a2c')
        from acme.signature import Signature
        self.signature = Signature(False, 'http://tester.local', self.logger)

    def test_001_signature__jwk_load(self):
        """ test jwk load """
        self.signature.dbstore.jwk_load.return_value = 'foo'
        self.assertEqual('foo', self.signature._jwk_load(1))

    def test_002_signature_check(self):
        """ test Signature.check() without having content """
        self.assertEqual((False, 'urn:ietf:params:acme:error:malformed', None),
                         self.signature.check('foo', None))

    @patch('acme.signature.Signature._jwk_load')
    def test_003_signature_check(self, mock_jwk):
        """ test Signature.check() while pubkey lookup failed """
        mock_jwk.return_value = {}
        self.assertEqual(
            (False, 'urn:ietf:params:acme:error:accountDoesNotExist', None),
            self.signature.check('foo', 1))

    @patch('acme.signature.signature_check')
    @patch('acme.signature.Signature._jwk_load')
    def test_004_signature_check(self, mock_jwk, mock_sig):
        """ test successful Signature.check()  """
        mock_jwk.return_value = {'foo': 'bar'}
        mock_sig.return_value = (True, None)
        self.assertEqual((True, None, None), self.signature.check('foo', 1))

    def test_005_signature_check(self):
        """ test successful Signature.check() without account_name and use_emb_key False"""
        self.assertEqual(
            (False, 'urn:ietf:params:acme:error:accountDoesNotExist', None),
            self.signature.check(None, 1, False))

    def test_006_signature_check(self):
        """ test successful Signature.check() without account_name and use_emb_key True but having a corrupted protected header"""
        protected = {'foo': 'foo'}
        self.assertEqual(
            (False, 'urn:ietf:params:acme:error:accountDoesNotExist', None),
            self.signature.check(None, 1, True, protected))

    @patch('acme.signature.signature_check')
    def test_007_signature_check(self, mock_sig):
        """ test successful Signature.check() with account_name and use_emb_key True, sigcheck returns something"""
        mock_sig.return_value = ('result', 'error')
        self.assertEqual(('result', 'error', None),
                         self.signature.check('foo', 1, True))

    @patch('acme.signature.signature_check')
    def test_008_signature_check(self, mock_sig):
        """ test successful Signature.check() without account_name and use_emb_key True, sigcheck returns something"""
        mock_sig.return_value = ('result', 'error')
        protected = {'url': 'url', 'jwk': 'jwk'}
        self.assertEqual(('result', 'error', None),
                         self.signature.check(None, 1, True, protected))

    def test_009_signature__jwk_load(self):
        """ test jwk load  - dbstore.jwk_load() raises an exception"""
        self.signature.dbstore.jwk_load.side_effect = Exception(
            'exc_sig_jw_load')
        with self.assertLogs('test_a2c', level='INFO') as lcm:
            self.signature._jwk_load(1)
        self.assertIn(
            'CRITICAL:test_a2c:acme2certifier database error in Signature._hwk_load(): exc_sig_jw_load',
            lcm.output)