|  | #!/usr/bin/env python3 | 
|  | """Generate server9-bad-saltlen.crt | 
|  |  | 
|  | Generate a certificate signed with RSA-PSS, with an incorrect salt length. | 
|  | """ | 
|  |  | 
|  | # Copyright The Mbed TLS Contributors | 
|  | # SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later | 
|  |  | 
|  | import subprocess | 
|  | import argparse | 
|  | from asn1crypto import pem, x509, core #type: ignore #pylint: disable=import-error | 
|  |  | 
|  | OPENSSL_RSA_PSS_CERT_COMMAND = r''' | 
|  | openssl x509 -req -CA {ca_name}.crt -CAkey {ca_name}.key -set_serial 24 {ca_password} \ | 
|  | {openssl_extfile} -days 3650 -outform DER -in {csr}  \ | 
|  | -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:{anounce_saltlen} \ | 
|  | -sigopt rsa_mgf1_md:sha256 | 
|  | ''' | 
|  | SIG_OPT = \ | 
|  | r'-sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:{saltlen} -sigopt rsa_mgf1_md:sha256' | 
|  | OPENSSL_RSA_PSS_DGST_COMMAND = r'''openssl dgst -sign {ca_name}.key {ca_password} \ | 
|  | -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:{actual_saltlen} \ | 
|  | -sigopt rsa_mgf1_md:sha256''' | 
|  |  | 
|  |  | 
|  | def auto_int(x): | 
|  | return int(x, 0) | 
|  |  | 
|  |  | 
|  | def build_argparser(parser): | 
|  | """Build argument parser""" | 
|  | parser.description = __doc__ | 
|  | parser.add_argument('--ca-name', type=str, required=True, | 
|  | help='Basename of CA files') | 
|  | parser.add_argument('--ca-password', type=str, | 
|  | required=True, help='CA key file password') | 
|  | parser.add_argument('--csr', type=str, required=True, | 
|  | help='CSR file for generating certificate') | 
|  | parser.add_argument('--openssl-extfile', type=str, | 
|  | required=True, help='X905 v3 extension config file') | 
|  | parser.add_argument('--anounce_saltlen', type=auto_int, | 
|  | required=True, help='Announced salt length') | 
|  | parser.add_argument('--actual_saltlen', type=auto_int, | 
|  | required=True, help='Actual salt length') | 
|  | parser.add_argument('--output', type=str, required=True) | 
|  |  | 
|  |  | 
|  | def main(): | 
|  | parser = argparse.ArgumentParser() | 
|  | build_argparser(parser) | 
|  | args = parser.parse_args() | 
|  |  | 
|  | return generate(**vars(args)) | 
|  |  | 
|  | def generate(**kwargs): | 
|  | """Generate different salt length certificate file.""" | 
|  | ca_password = kwargs.get('ca_password', '') | 
|  | if ca_password: | 
|  | kwargs['ca_password'] = r'-passin "pass:{ca_password}"'.format( | 
|  | **kwargs) | 
|  | else: | 
|  | kwargs['ca_password'] = '' | 
|  | extfile = kwargs.get('openssl_extfile', '') | 
|  | if extfile: | 
|  | kwargs['openssl_extfile'] = '-extfile {openssl_extfile}'.format( | 
|  | **kwargs) | 
|  | else: | 
|  | kwargs['openssl_extfile'] = '' | 
|  |  | 
|  | cmd = OPENSSL_RSA_PSS_CERT_COMMAND.format(**kwargs) | 
|  | der_bytes = subprocess.check_output(cmd, shell=True) | 
|  | target_certificate = x509.Certificate.load(der_bytes) | 
|  |  | 
|  | cmd = OPENSSL_RSA_PSS_DGST_COMMAND.format(**kwargs) | 
|  | #pylint: disable=unexpected-keyword-arg | 
|  | der_bytes = subprocess.check_output(cmd, | 
|  | input=target_certificate['tbs_certificate'].dump(), | 
|  | shell=True) | 
|  |  | 
|  | with open(kwargs.get('output'), 'wb') as f: | 
|  | target_certificate['signature_value'] = core.OctetBitString(der_bytes) | 
|  | f.write(pem.armor('CERTIFICATE', target_certificate.dump())) | 
|  |  | 
|  |  | 
|  | if __name__ == '__main__': | 
|  | main() |