Jerry Yu | a3d911b | 2023-05-23 17:21:52 +0800 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | """Generate server9-bad-saltlen.crt |
| 3 | |
Jerry Yu | baf7ba4 | 2023-10-24 15:44:00 +0800 | [diff] [blame] | 4 | Generate a certificate signed with RSA-PSS, with an incorrect salt length. |
Jerry Yu | a3d911b | 2023-05-23 17:21:52 +0800 | [diff] [blame] | 5 | """ |
| 6 | |
| 7 | # Copyright The Mbed TLS Contributors |
| 8 | # SPDX-License-Identifier: Apache-2.0 |
| 9 | # |
| 10 | # Licensed under the Apache License, Version 2.0 (the "License"); you may |
| 11 | # not use this file except in compliance with the License. |
| 12 | # You may obtain a copy of the License at |
| 13 | # |
| 14 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 15 | # |
| 16 | # Unless required by applicable law or agreed to in writing, software |
| 17 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 18 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 19 | # See the License for the specific language governing permissions and |
| 20 | # limitations under the License. |
| 21 | |
| 22 | import subprocess |
| 23 | import argparse |
| 24 | from asn1crypto import pem, x509, core #type: ignore #pylint: disable=import-error |
| 25 | |
| 26 | OPENSSL_RSA_PSS_CERT_COMMAND = r''' |
| 27 | openssl x509 -req -CA {ca_name}.crt -CAkey {ca_name}.key -set_serial 24 {ca_password} \ |
| 28 | {openssl_extfile} -days 3650 -outform DER -in {csr} \ |
| 29 | -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:{anounce_saltlen} \ |
| 30 | -sigopt rsa_mgf1_md:sha256 |
| 31 | ''' |
| 32 | SIG_OPT = \ |
| 33 | r'-sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:{saltlen} -sigopt rsa_mgf1_md:sha256' |
| 34 | OPENSSL_RSA_PSS_DGST_COMMAND = r'''openssl dgst -sign {ca_name}.key {ca_password} \ |
| 35 | -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:{actual_saltlen} \ |
| 36 | -sigopt rsa_mgf1_md:sha256''' |
| 37 | |
| 38 | |
| 39 | def auto_int(x): |
| 40 | return int(x, 0) |
| 41 | |
| 42 | |
| 43 | def build_argparser(parser): |
| 44 | """Build argument parser""" |
| 45 | parser.description = __doc__ |
| 46 | parser.add_argument('--ca-name', type=str, required=True, |
| 47 | help='Basename of CA files') |
| 48 | parser.add_argument('--ca-password', type=str, |
| 49 | required=True, help='CA key file password') |
| 50 | parser.add_argument('--csr', type=str, required=True, |
| 51 | help='CSR file for generating certificate') |
| 52 | parser.add_argument('--openssl-extfile', type=str, |
| 53 | required=True, help='X905 v3 extension config file') |
| 54 | parser.add_argument('--anounce_saltlen', type=auto_int, |
| 55 | required=True, help='Announced salt length') |
| 56 | parser.add_argument('--actual_saltlen', type=auto_int, |
| 57 | required=True, help='Actual salt length') |
| 58 | parser.add_argument('--output', type=str, required=True) |
| 59 | |
| 60 | |
| 61 | def main(): |
| 62 | parser = argparse.ArgumentParser() |
| 63 | build_argparser(parser) |
| 64 | args = parser.parse_args() |
| 65 | |
| 66 | return generate(**vars(args)) |
| 67 | |
| 68 | def generate(**kwargs): |
Jerry Yu | 2f3f968 | 2023-10-18 15:06:54 +0800 | [diff] [blame] | 69 | """Generate different salt length certificate file.""" |
Jerry Yu | a3d911b | 2023-05-23 17:21:52 +0800 | [diff] [blame] | 70 | ca_password = kwargs.get('ca_password', '') |
| 71 | if ca_password: |
| 72 | kwargs['ca_password'] = r'-passin "pass:{ca_password}"'.format( |
| 73 | **kwargs) |
| 74 | else: |
| 75 | kwargs['ca_password'] = '' |
| 76 | extfile = kwargs.get('openssl_extfile', '') |
| 77 | if extfile: |
| 78 | kwargs['openssl_extfile'] = '-extfile {openssl_extfile}'.format( |
| 79 | **kwargs) |
| 80 | else: |
| 81 | kwargs['openssl_extfile'] = '' |
| 82 | |
| 83 | cmd = OPENSSL_RSA_PSS_CERT_COMMAND.format(**kwargs) |
| 84 | der_bytes = subprocess.check_output(cmd, shell=True) |
| 85 | target_certificate = x509.Certificate.load(der_bytes) |
| 86 | |
| 87 | cmd = OPENSSL_RSA_PSS_DGST_COMMAND.format(**kwargs) |
| 88 | #pylint: disable=unexpected-keyword-arg |
| 89 | der_bytes = subprocess.check_output(cmd, |
| 90 | input=target_certificate['tbs_certificate'].dump(), |
| 91 | shell=True) |
| 92 | |
| 93 | with open(kwargs.get('output'), 'wb') as f: |
| 94 | target_certificate['signature_value'] = core.OctetBitString(der_bytes) |
| 95 | f.write(pem.armor('CERTIFICATE', target_certificate.dump())) |
| 96 | |
| 97 | |
| 98 | if __name__ == '__main__': |
| 99 | main() |