1#!/usr/bin/env python3 2"""Generate server9-bad-saltlen.crt 3 4Generate a certificate signed with RSA-PSS, with an incorrect salt length. 5""" 6 7# Copyright The Mbed TLS Contributors 8# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 9 10import subprocess 11import argparse 12from asn1crypto import pem, x509, core #type: ignore #pylint: disable=import-error 13 14OPENSSL_RSA_PSS_CERT_COMMAND = r''' 15openssl x509 -req -CA {ca_name}.crt -CAkey {ca_name}.key -set_serial 24 {ca_password} \ 16 {openssl_extfile} -days 3650 -outform DER -in {csr} \ 17 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:{anounce_saltlen} \ 18 -sigopt rsa_mgf1_md:sha256 19''' 20SIG_OPT = \ 21 r'-sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:{saltlen} -sigopt rsa_mgf1_md:sha256' 22OPENSSL_RSA_PSS_DGST_COMMAND = r'''openssl dgst -sign {ca_name}.key {ca_password} \ 23 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:{actual_saltlen} \ 24 -sigopt rsa_mgf1_md:sha256''' 25 26 27def auto_int(x): 28 return int(x, 0) 29 30 31def build_argparser(parser): 32 """Build argument parser""" 33 parser.description = __doc__ 34 parser.add_argument('--ca-name', type=str, required=True, 35 help='Basename of CA files') 36 parser.add_argument('--ca-password', type=str, 37 required=True, help='CA key file password') 38 parser.add_argument('--csr', type=str, required=True, 39 help='CSR file for generating certificate') 40 parser.add_argument('--openssl-extfile', type=str, 41 required=True, help='X905 v3 extension config file') 42 parser.add_argument('--anounce_saltlen', type=auto_int, 43 required=True, help='Announced salt length') 44 parser.add_argument('--actual_saltlen', type=auto_int, 45 required=True, help='Actual salt length') 46 parser.add_argument('--output', type=str, required=True) 47 48 49def main(): 50 parser = argparse.ArgumentParser() 51 build_argparser(parser) 52 args = parser.parse_args() 53 54 return generate(**vars(args)) 55 56def generate(**kwargs): 57 """Generate different salt length certificate file.""" 58 ca_password = kwargs.get('ca_password', '') 59 if ca_password: 60 kwargs['ca_password'] = r'-passin "pass:{ca_password}"'.format( 61 **kwargs) 62 else: 63 kwargs['ca_password'] = '' 64 extfile = kwargs.get('openssl_extfile', '') 65 if extfile: 66 kwargs['openssl_extfile'] = '-extfile {openssl_extfile}'.format( 67 **kwargs) 68 else: 69 kwargs['openssl_extfile'] = '' 70 71 cmd = OPENSSL_RSA_PSS_CERT_COMMAND.format(**kwargs) 72 der_bytes = subprocess.check_output(cmd, shell=True) 73 target_certificate = x509.Certificate.load(der_bytes) 74 75 cmd = OPENSSL_RSA_PSS_DGST_COMMAND.format(**kwargs) 76 #pylint: disable=unexpected-keyword-arg 77 der_bytes = subprocess.check_output(cmd, 78 input=target_certificate['tbs_certificate'].dump(), 79 shell=True) 80 81 with open(kwargs.get('output'), 'wb') as f: 82 target_certificate['signature_value'] = core.OctetBitString(der_bytes) 83 f.write(pem.armor('CERTIFICATE', target_certificate.dump())) 84 85 86if __name__ == '__main__': 87 main() 88