2023-05-23 11:21:52 +02:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
"""Generate server9-bad-saltlen.crt
|
|
|
|
|
2023-10-24 09:44:00 +02:00
|
|
|
Generate a certificate signed with RSA-PSS, with an incorrect salt length.
|
2023-05-23 11:21:52 +02:00
|
|
|
"""
|
|
|
|
|
|
|
|
# Copyright The Mbed TLS Contributors
|
|
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
#
|
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
|
|
# not use this file except in compliance with the License.
|
|
|
|
# You may obtain a copy of the License at
|
|
|
|
#
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
#
|
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
# See the License for the specific language governing permissions and
|
|
|
|
# limitations under the License.
|
|
|
|
|
|
|
|
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):
|
2023-10-18 09:06:54 +02:00
|
|
|
"""Generate different salt length certificate file."""
|
2023-05-23 11:21:52 +02:00
|
|
|
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()
|