Esempio n. 1
0
 def test_dsa_verify(self):
     with open(os.path.join(fixtures_dir, 'message.txt'), 'rb') as f:
         original_data = f.read()
     with open(os.path.join(fixtures_dir, 'dsa_signature'), 'rb') as f:
         signature = f.read()
     public = asymmetric.load_public_key(os.path.join(fixtures_dir, 'keys/test-dsa-1024.crt'))
     asymmetric.dsa_verify(public, signature, original_data, 'sha1')
Esempio n. 2
0
 def test_dsa_verify(self):
     with open(os.path.join(fixtures_dir, 'message.txt'), 'rb') as f:
         original_data = f.read()
     with open(os.path.join(fixtures_dir, 'dsa_signature'), 'rb') as f:
         signature = f.read()
     public = asymmetric.load_public_key(os.path.join(fixtures_dir, 'keys/test-dsa-1024.crt'))
     asymmetric.dsa_verify(public, signature, original_data, 'sha1')
Esempio n. 3
0
 def test_dsa_verify_fail(self):
     with open(os.path.join(fixtures_dir, 'message.txt'), 'rb') as f:
         original_data = f.read()
     with open(os.path.join(fixtures_dir, 'dsa_signature'), 'rb') as f:
         signature = f.read()
     public = asymmetric.load_public_key(os.path.join(fixtures_dir, 'keys/test-dsa-1024.crt'))
     with self.assertRaises(errors.SignatureError):
         asymmetric.dsa_verify(public, signature, original_data + b'1', 'sha1')
Esempio n. 4
0
 def test_dsa_verify_key_size_mismatch(self):
     with open(os.path.join(fixtures_dir, 'message.txt'), 'rb') as f:
         original_data = f.read()
     with open(os.path.join(fixtures_dir, 'dsa_signature'), 'rb') as f:
         signature = f.read()
     public = asymmetric.load_public_key(
         os.path.join(fixtures_dir, 'keys/test-dsa-512.crt'))
     with self.assertRaises(errors.SignatureError):
         asymmetric.dsa_verify(public, signature, original_data, 'sha1')
Esempio n. 5
0
        def do_run():
            original_data = b'This is data to sign'
            private = asymmetric.load_private_key(os.path.join(fixtures_dir, 'keys/test-dsa.key'))
            public = asymmetric.load_public_key(os.path.join(fixtures_dir, 'keys/test-dsa.crt'))

            signature = asymmetric.dsa_sign(private, original_data, 'sha1')
            self.assertIsInstance(signature, byte_cls)

            asymmetric.dsa_verify(public, signature, original_data, 'sha1')
Esempio n. 6
0
        def do_run():
            original_data = b'This is data to sign'
            private = asymmetric.load_private_key(os.path.join(fixtures_dir, 'keys/test-dsa.key'))
            public = asymmetric.load_public_key(os.path.join(fixtures_dir, 'keys/test-dsa.crt'))

            signature = asymmetric.dsa_sign(private, original_data, 'sha1')
            self.assertIsInstance(signature, byte_cls)

            asymmetric.dsa_verify(public, signature, original_data, 'sha1')
Esempio n. 7
0
    def test_dsa_generate(self):
        public, private = asymmetric.generate_pair('dsa', bit_size=1024)

        self.assertEqual('dsa', public.algorithm)
        self.assertEqual(1024, public.bit_size)

        original_data = b'This is data to sign'
        signature = asymmetric.dsa_sign(private, original_data, 'sha1')
        self.assertIsInstance(signature, byte_cls)
        asymmetric.dsa_verify(public, signature, original_data, 'sha1')
Esempio n. 8
0
    def test_dsa_generate(self):
        public, private = asymmetric.generate_pair('dsa', bit_size=1024)

        self.assertEqual('dsa', public.algorithm)
        self.assertEqual(1024, public.bit_size)

        original_data = b'This is data to sign'
        signature = asymmetric.dsa_sign(private, original_data, 'sha1')
        self.assertIsInstance(signature, byte_cls)
        asymmetric.dsa_verify(public, signature, original_data, 'sha1')
Esempio n. 9
0
 def test_dsa_verify_fail_each_byte(self):
     with open(os.path.join(fixtures_dir, 'message.txt'), 'rb') as f:
         original_data = f.read()
     with open(os.path.join(fixtures_dir, 'dsa_signature'), 'rb') as f:
         original_signature = f.read()
     public = asymmetric.load_public_key(os.path.join(fixtures_dir, 'keys/test-dsa-1024.crt'))
     for i in range(0, len(original_signature)):
         if i == 0:
             signature = b'\xab' + original_signature[1:]
         elif i == len(original_signature) - 1:
             signature = original_signature[0:-1] + b'\xab'
         else:
             signature = original_signature[0:i] + b'\xab' + original_signature[i+1:]
         with self.assertRaises(errors.SignatureError):
             asymmetric.dsa_verify(public, signature, original_data+ b'1', 'sha1')
Esempio n. 10
0
 def test_dsa_verify_fail_each_byte(self):
     with open(os.path.join(fixtures_dir, 'message.txt'), 'rb') as f:
         original_data = f.read()
     with open(os.path.join(fixtures_dir, 'dsa_signature'), 'rb') as f:
         original_signature = f.read()
     public = asymmetric.load_public_key(
         os.path.join(fixtures_dir, 'keys/test-dsa-1024.crt'))
     for i in range(0, len(original_signature)):
         if i == 0:
             signature = b'\xab' + original_signature[1:]
         elif i == len(original_signature) - 1:
             signature = original_signature[0:-1] + b'\xab'
         else:
             signature = original_signature[
                 0:i] + b'\xab' + original_signature[i + 1:]
         with self.assertRaises(errors.SignatureError):
             asymmetric.dsa_verify(public, signature, original_data + b'1',
                                   'sha1')
Esempio n. 11
0
    def test_dsa_generate(self):
        public, private = asymmetric.generate_pair('dsa', bit_size=1024)

        self.assertEqual('dsa', public.algorithm)
        self.assertEqual(1024, public.bit_size)

        original_data = b'This is data to sign'
        signature = asymmetric.dsa_sign(private, original_data, 'sha1')
        self.assertIsInstance(signature, byte_cls)
        asymmetric.dsa_verify(public, signature, original_data, 'sha1')

        raw_public = asymmetric.dump_public_key(public)
        asymmetric.load_public_key(raw_public)
        raw_private = asymmetric.dump_private_key(private, None)
        asymmetric.load_private_key(raw_private, None)

        self.assertIsInstance(private.fingerprint, byte_cls)
        self.assertIsInstance(public.fingerprint, byte_cls)
        self.assertEqual(private.fingerprint, public.fingerprint)
Esempio n. 12
0
def validate_ocsp_response(cert, issuer, ocsp_request_obj, ocsp_response_objs,
                           current_time):
    #print(cert.ocsp_urls) # Just to see how many urls there are
    subject = cert['tbs_certificate']['subject'].native
    errors = {}
    warnings = {}
    lints_list = []
    count = 0
    lints = {}

    for (ocsp_url, ocsp_response_obj) in ocsp_response_objs:
        count += 1
        lints['domain'] = subject['common_name']
        lints['ocsp_url'] = ocsp_url
        lints['response_count'] = count
        #print(ocsp_response_obj.native)
        errors = {}
        warnings = {}
        if isinstance(ocsp_response_obj, urllib.error.HTTPError):
            errors['HTTPError'] = str(ocsp_response_obj)
            lints['errors'] = errors
            lints['warnings'] = warnings
            lints_list.append(lints)
            return lints_list

        if isinstance(ocsp_response_obj, ValueError):
            errors['ValueError'] = str(ocsp_response_obj)
            lints['errors'] = errors
            lints['warnings'] = warnings
            lints_list.append(lints)
            return lints_list

        if (ocsp_response_obj['response_status'].native == 'unauthorized'):
            errors['Unauthorized'] = 'Responder returned unauthorized'
            lints['errors'] = errors
            lints['warnings'] = warnings
            lints_list.append(lints)
            continue

        if (ocsp_response_obj['response_status'].native == 'malformed_request'
            ):
            errors['ResponseFailure'] = 'Responder returned malformed request'
            lints['errors'] = errors
            lints['warnings'] = warnings
            lints_list.append(lints)
            continue

        request_nonce = ocsp_request_obj.nonce_value
        #print (ocsp_response_obj.native)
        response_nonce = ocsp_response_obj.nonce_value
        if request_nonce and response_nonce and request_nonce.native != response_nonce.native:
            errors[
                'NonceVerificationFailure'] = 'Unable to verify OCSP response since the request and response nonces do not match'

        if ocsp_response_obj['response_status'].native != 'successful':
            errors['OCSPCheckFailure'] = 'OCSP check returned as failed'

        response_bytes = ocsp_response_obj['response_bytes']
        if response_bytes['response_type'].native != 'basic_ocsp_response':
            errors[
                'ResponseTypeFailure'] = 'OCSP response is not Basic OCSP Response'

        parsed_response = response_bytes['response'].parsed
        tbs_response = parsed_response['tbs_response_data']
        certificate_response = tbs_response['responses'][0]

        certificate_id = certificate_response['cert_id']
        algo = certificate_id['hash_algorithm']['algorithm'].native

        certificate_issuer_name_hash = certificate_id[
            'issuer_name_hash'].native
        certificate_issuer_key_hash = certificate_id['issuer_key_hash'].native
        certificate_serial_number = certificate_id['serial_number'].native

        certificate_issuer_name_hash_from_file = getattr(cert.issuer, algo)
        certificate_issuer_key_hash_from_file = getattr(
            issuer.public_key, algo)
        certificate_serial_number_from_file = cert.serial_number

        if certificate_serial_number != certificate_serial_number_from_file:
            errors['CertificateSerialMismatchFailure'] = \
            'OCSP response certificate serial number does not match request certificate serial number'

        if certificate_issuer_key_hash != certificate_issuer_key_hash_from_file:
            errors[
                'IssuerKeyMismatchFailure'] = 'OCSP response issuer key hash does not match request certificate issuer key hash'

        if certificate_issuer_name_hash != certificate_issuer_name_hash_from_file:
            errors['IssuerNameHashMismatchFailure'] = \
                'OCSP response issuer name hash does not match request certificate issuer name hash'

        this_update_time = certificate_response['this_update'].native
        if current_time < this_update_time:
            errors[
                'ThisUpdateTimeError'] = 'OCSP reponse update time is from the future'

        if "next_update" not in certificate_response or certificate_response[
                'next_update'].native is None:
            warnings[
                'NextUpdateTimeMissing'] = 'OCSP response does not contain next update time'
        else:
            next_update_time = certificate_response['next_update'].native
            if current_time > next_update_time:
                errors[
                    'NextUpdateTimeFailure'] = 'OCSP reponse next update time is in the past'

        registry = CertificateRegistry(trust_roots=[issuer])

        if tbs_response['responder_id'].name == 'by_key':
            key_identifier = tbs_response['responder_id'].native
            signing_cert = registry.retrieve_by_key_identifier(key_identifier)

        elif tbs_response['responder_id'].name == 'by_name':
            signing_certs = registry.retrieve_by_name(
                tbs_response['responder_id'].chosen, None)
            if signing_certs is not None and len(signing_certs) > 0:
                signing_cert = signing_certs[0]
            else:
                signing_cert = None

        if signing_cert is None:
            errors[
                'SigningCetificateNotFoundFailure'] = 'OCSP response signing certificate not found'
            lints['errors'] = errors
            lints['warnings'] = warnings
            lints_list.append(lints)
            continue

        if issuer.issuer_serial != signing_cert.issuer_serial:
            if signing_cert_issuer.issuer_serial != issuer.issuer_serial:
                errors[
                    'UnauthorizedSigningCertificateFailure'] = 'OCSP response signed by unauthorized certificate'

            extended_key_usage = signing_cert.extended_key_usage_value
            if 'ocsp_signing' not in extended_key_usage.native:
                errors['ExtendedKeyUsageExtensionValueFailure'] = \
                    'OCSP response signing certificate is not the issuing certificate and it does not have value "ocsp_signing"\
                    for the extended key usage extension'

        sig_algo = parsed_response['signature_algorithm'].signature_algo
        hash_algo = parsed_response['signature_algorithm'].hash_algo
        try:
            check_cert = asymmetric.load_certificate(signing_cert)
            if sig_algo == 'rsassa_pkcs1v15':
                asymmetric.rsa_pkcs1v15_verify(
                    check_cert, parsed_response['signature'].native,
                    tbs_response.dump(), hash_algo)
            elif sig_algo == 'dsa':
                asymmetric.dsa_verify(check_cert,
                                      parsed_response['signature'].native,
                                      tbs_response.dump(), hash_algo)
            elif sig_algo == 'ecdsa':
                asymmetric.ecdsa_verify(check_cert,
                                        parsed_response['signature'].native,
                                        tbs_response.dump(), hash_algo)
            else:
                errors[
                    'UnsupportedAlgorithmFailure'] = 'OCSP response signature uses unsupported algorithm'

        except (oscrypto.errors.SignatureError):
            errors[
                'SignatureVerificationFailure'] = 'OCSP response signature could not be verified'

        if certificate_response['cert_status'].name == 'revoked':
            revocation_data = certificate_response['cert_status'].chosen
            if revocation_data['revocation_reason'].native is None:
                errors[
                    'CertificateValidityFailure'] = 'Certificate revoked due to unknown reason'
            else:
                errors[
                    'CertificateValidityFailure'] = 'Certicate revoked due to ' + revocation_data[
                        'revocation_reason'].human_friendly

        if 'certs' in parsed_response and parsed_response[
                'certs'].native != None:
            #TODO Check for legit certs
            pass


#            print(parsed_response['certs'].native)

        if len(errors) == 0:
            errors['NoFailure'] = 'No errors in OCSP response'
        if len(warnings) == 0:
            warnings['NoWarning'] = 'No warnings in OCSP response'

        lints['errors'] = errors
        lints['warnings'] = warnings
        lints_list.append(lints)

    return lints_list