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')
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')
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')
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')
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')
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')
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')
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')
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')
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')
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)
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