Skip to content

Commit

Permalink
String interpolation with f-strings (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
psmiraglia authored Apr 16, 2021
1 parent 878d1ee commit 0ba87db
Show file tree
Hide file tree
Showing 11 changed files with 56 additions and 75 deletions.
18 changes: 8 additions & 10 deletions bin/spid-compliant-certificates
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ class SortingHelpFormatter(argparse.ArgumentDefaultsHelpFormatter):

def not_empty_string(value):
if not re.match(r'^\S(.*\S)?$', value):
emsg = 'Format "%s" is not accepted' % value
emsg = f'Format "{value}" is not accepted'
raise argparse.ArgumentTypeError(emsg)
return value


def logo():
print('''
print(f'''
_____ _____ _____ _____ _____ _ _ _
/ ____| __ \_ _| __ \ / ____| | (_) | |
| (___ | |__) || | | | | | | | ___ _ __ ___ _ __ | |_ __ _ _ __ | |_
Expand All @@ -62,10 +62,10 @@ def logo():
| | ___ _ __| |_ _| |_ _ ___ __ _| |_ ___ ___
| | / _ \ '__| __| | _| |/ __/ _` | __/ _ \/ __|
| |___| __/ | | |_| | | | | (_| (_| | || __/\__ \\
\_____\___|_| \__|_|_| |_|\___\__,_|\__\___||___/ v%s
\_____\___|_| \__|_|_| |_|\___\__,_|\__\___||___/ v{version}
''' % version) # noqa
''') # noqa

# main

Expand Down Expand Up @@ -234,19 +234,17 @@ if __name__ == '__main__':
sys.exit(1)
elif args.mode == 'validator':
if not args.crt_file.exists():
LOG.error('Unable to find certificate file %s' % args.crt_file)
LOG.error(f'Unable to find certificate file {args.crt_file}')
sys.exit(1)
try:
LOG.info(
'Validating certificate %s against %s sector specifications'
% (args.crt_file, args.sector)
)
LOG.info(f'Validating certificate {args.crt_file} '
+ f'against {args.sector} sector specifications')
validate(args.crt_file, args.sector)
except Exception as e:
LOG.error(e)
sys.exit(1)
else:
LOG.error('Invalid mode (%s)' % args.mode)
LOG.error(f'Invalid mode ({args.mode})')
sys.exit(1)

sys.exit(0)
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,5 @@ def long_description():
packages=find_packages(exclude=['bin']),
install_requires=get_requirements(),
scripts=['bin/spid-compliant-certificates'],
python_requires='>=3.6',
)
35 changes: 15 additions & 20 deletions spid_compliant_certificates/generator/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def _validate_private_arguments(cert_opts: Dict) -> None:
pattern = r'^(CF:IT-[a-zA-Z0-9]{16}|VATIT-\d{11})$'
org_id = cert_opts['org_id']
if not re.match(pattern, org_id):
emsg = ('Invalid value for organization identifier (%s)' % org_id)
emsg = (f'Invalid value for organization identifier ({org_id})')
raise ValueError(emsg)


Expand All @@ -54,7 +54,7 @@ def _validate_public_arguments(cert_opts: Dict) -> None:
pattern = r'^PA:IT-\S{1,11}$'
org_id = cert_opts['org_id']
if not re.match(pattern, org_id):
emsg = ('Invalid value for organization identifier (%s)' % org_id)
emsg = (f'Invalid value for organization identifier ({org_id})')
raise ValueError(emsg)

# check if the ipa code is valid
Expand Down Expand Up @@ -88,7 +88,7 @@ def _validate_public_arguments(cert_opts: Dict) -> None:

if not res['risposta']['listaResponse']:
emsg = [
'The IPA code (%s) refers to something that does not exist.' % ipa_code, # noqa
f'The IPA code ({ipa_code}) refers to something that does not exist.', # noqa
'Check it by yourself at https://indicepa.gov.it/ipa-portale/consultazione/indirizzo-sede/ricerca-ente' # noqa
]
raise ValueError(' '.join(emsg))
Expand All @@ -101,7 +101,7 @@ def _validate_public_arguments(cert_opts: Dict) -> None:

if not ipa_code_is_valid:
emsg = [
'The IPA code (%s) refers to something that does not exist.' % ipa_code, # noqa
f'The IPA code ({ipa_code}) refers to something that does not exist.', # noqa
'Check it by yourself at https://indicepa.gov.it/ipa-portale/consultazione/indirizzo-sede/ricerca-ente' # noqa
]
raise ValueError(' '.join(emsg))
Expand All @@ -114,14 +114,14 @@ def validate_arguments(cert_opts: Dict) -> None:
elif sector == 'public':
_validate_public_arguments(cert_opts)
else:
emsg = 'Invalid value for sector (%s)' % sector
emsg = f'Invalid value for sector ({sector})'
raise Exception(emsg)


def gen_private_key(key_size: int, key_out: pathlib.PosixPath) -> rsa.RSAPrivateKey: # noqa
# check if the private key file already exists
if key_out.exists():
emsg = 'File %s already exists' % key_out
emsg = f'File {key_out} already exists'
raise Exception(emsg)

# generate private key
Expand Down Expand Up @@ -193,7 +193,7 @@ def _extensions(key: rsa.RSAPrivateKey, cert_opts: Dict) -> List[Tuple[bool, x50
)
)
else:
emsg = 'Invalid value for sector (%s)' % sector
emsg = f'Invalid value for sector ({sector})'
raise Exception(emsg)

# extensions list
Expand Down Expand Up @@ -301,26 +301,21 @@ def generate(cert_opts: Dict, crypto_opts: Dict) -> None:
key_size = crypto_opts['key_size']
key_out = crypto_opts['key_out']
key = gen_private_key(key_size, key_out)
LOG.info('Private key saved to %s' % key_out)
LOG.info(' Inspect with OpenSSL: openssl rsa -in %s -noout -text'
% key_out)
LOG.info(f'Private key saved to {key_out}')
LOG.info(f' Inspect with OpenSSL: openssl rsa -in {key_out} -noout -text')

# generate the csr
csr_out = crypto_opts['csr_out']
gen_csr(key, cert_opts, crypto_opts)
LOG.info('CSR saved to %s' % csr_out)
LOG.info(' Inspect with OpenSSL: openssl req -in %s -noout -text'
% csr_out)
LOG.info(' Inspect with OpenSSL: openssl asn1parse -i -inform PEM -in %s'
% csr_out)
LOG.info(f'CSR saved to {csr_out}')
LOG.info(f' Inspect with OpenSSL: openssl req -in {csr_out} -noout -text')
LOG.info(f' Inspect with OpenSSL: openssl asn1parse -i -inform PEM -in {csr_out}') # noqa

# generate self-signed certificate
sector = cert_opts['sector']
crt_out = crypto_opts['crt_out']
if sector == 'public':
gen_self_signed(key, cert_opts, crypto_opts)
LOG.info('Self-signed certificate saved to %s' % crt_out)
LOG.info(' Inspect with OpenSSL: openssl x509 -noout -text -in %s'
% crt_out)
LOG.info((' Inspect with OpenSSL: '
+ 'openssl asn1parse -i -inform PEM -in %s') % crt_out)
LOG.info(f'Self-signed certificate saved to {crt_out}')
LOG.info(f' Inspect with OpenSSL: openssl x509 -noout -text -in {crt_out}') # noqa
LOG.info(f' Inspect with OpenSSL: openssl asn1parse -i -inform PEM -in {crt_out}') # noqa
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ def basic_constraints(extensions: x509.Extensions) -> List[Tuple[bool, str]]:
try:
ext = extensions.get_extension_for_class(ext_cls)

msg = '%s can not be set as critical' % ext_name
msg = f'{ext_name} can not be set as critical'
res = FAILURE if ext.critical else SUCCESS
checks.append((res, msg))

msg = 'CA must be FALSE'
res = FAILURE if ext.value.ca else SUCCESS
checks.append((res, msg))
except x509.ExtensionNotFound:
msg = '%s must be present' % ext_name
msg = f'{ext_name} must be present'
checks.append((FAILURE, msg))

return checks
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def certificate_policies(extensions: x509.Extensions, sector: str) -> List[Tuple
ext = extensions.get_extension_for_class(ext_cls)

# check if critical
msg = '%s can not be set as critical' % ext_name
msg = f'{ext_name} can not be set as critical'
res = FAILURE if ext.critical else SUCCESS
checks.append((res, msg))

Expand All @@ -58,7 +58,7 @@ def certificate_policies(extensions: x509.Extensions, sector: str) -> List[Tuple
is_present = any(
p.policy_identifier.dotted_string == ep for p in policies
)
msg = 'policy %s must be present' % (ep)
msg = f'policy {ep} must be present'
res = SUCCESS if is_present else FAILURE
checks.append((res, msg))

Expand All @@ -71,9 +71,8 @@ def certificate_policies(extensions: x509.Extensions, sector: str) -> List[Tuple
exp_etext = 'agIDcert'
etext = q.explicit_text

msg = 'policy %s must have ' % (oid)
msg += ('UserNotice.ExplicitText=%s (now: %s)'
% (exp_etext, etext))
msg = f'policy {oid} must have '
msg += f'UserNotice.ExplicitText={exp_etext} (now: {etext})' # noqa

res = FAILURE if etext != exp_etext else SUCCESS
checks.append((res, msg))
Expand All @@ -84,9 +83,8 @@ def certificate_policies(extensions: x509.Extensions, sector: str) -> List[Tuple
exp_etext = 'cert_SP_Pub'
etext = q.explicit_text

msg = 'policy %s must have ' % (oid)
msg += ('UserNotice.ExplicitText=%s (now: %s)'
% (exp_etext, etext))
msg = f'policy {oid} must have '
msg += f'UserNotice.ExplicitText={exp_etext} (now: {etext})' # noqa

res = FAILURE if etext != exp_etext else SUCCESS
checks.append((res, msg))
Expand All @@ -96,14 +94,13 @@ def certificate_policies(extensions: x509.Extensions, sector: str) -> List[Tuple
exp_etext = 'cert_SP_Priv'
etext = q.explicit_text

msg = 'policy %s must have ' % (oid)
msg += ('UserNotice.ExplicitText=%s (now: %s)'
% (exp_etext, etext))
msg = f'policy {oid} must have '
msg += f'UserNotice.ExplicitText={exp_etext} (now: {etext})' # noqa

res = FAILURE if etext != exp_etext else SUCCESS
checks.append((res, msg))
except x509.ExtensionNotFound:
msg = '%s must be present' % ext_name
msg = f'{ext_name} must be present'
checks.append((FAILURE, msg))

return checks
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@
def digest_algorithm(alg: str) -> List[Tuple[bool, str]]:
checks = []

msg = ('The digest algorithm must be one of %s (now: %s)'
% (ALLOWED_ALGS, alg))
msg = f'The digest algorithm must be one of {ALLOWED_ALGS} (now: {alg})'
res = FAILURE if alg not in ALLOWED_ALGS else SUCCESS
checks.append((res, msg))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,19 @@ def key_type_and_size(cert: x509.Certificate) -> List[Tuple[bool, str]]:
# check the keypair type
exp_pk_type = 'RSA'
pk_type = 'RSA' if isinstance(pk, rsa.RSAPublicKey) else 'NOT ALLOWED'
msg = 'The keypair must be %s' % exp_pk_type
msg = f'The keypair must be {exp_pk_type}'
res = FAILURE if pk_type != exp_pk_type else SUCCESS
checks.append((res, msg))

# check the key size
min_size = 2048
size = pk.key_size

msg = ('The key size must be greater than or equal to %d (now: %d)'
% (min_size, size))
msg = f'The key size must be greater than or equal to {min_size} (now: {size})' # noqa
res = FAILURE if size < min_size else SUCCESS
checks.append((res, msg))

msg = ('The key size must be one of %s (now: %d)'
% (ALLOWED_SIZES, size))
msg = f'The key size must be one of {ALLOWED_SIZES} (now: {size})'
res = FAILURE if size not in ALLOWED_SIZES else SUCCESS
checks.append((res, msg))

Expand Down
8 changes: 4 additions & 4 deletions spid_compliant_certificates/validator/checks/key_usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,22 @@ def key_usage(extensions: x509.Extensions) -> List[Tuple[bool, str]]:
try:
ext = extensions.get_extension_for_class(ext_cls)

msg = '%s must be set as critical' % ext_name
msg = f'{ext_name} must be set as critical'
res = FAILURE if not ext.critical else SUCCESS
checks.append((res, msg))

for usage in ['content_commitment', 'digital_signature']:
msg = '%s must be set' % (usage)
msg = f'{usage} must be set'
res = FAILURE if not getattr(ext.value, usage) else SUCCESS
checks.append((res, msg))

for usage in ['crl_sign', 'data_encipherment', 'key_agreement',
'key_cert_sign', 'key_encipherment']:
msg = '%s must be unset' % (usage)
msg = f'{usage} must be unset'
res = FAILURE if getattr(ext.value, usage) else SUCCESS
checks.append((res, msg))
except x509.ExtensionNotFound:
msg = '%s must be present' % ext_name
msg = f'{ext_name} must be present'
res = FAILURE
checks.append((res, msg))

Expand Down
18 changes: 6 additions & 12 deletions spid_compliant_certificates/validator/checks/subject_dn.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,19 @@ def subject_dn(subj: x509.Name, sector: str) -> List[Tuple[bool, str]]:

# check if not allowed attrs are present
for attr in NOT_ALLOWED_ATTRS:
msg = ('Name attribute [%s, %s] is not allowed in subjectDN'
% (attr._name, attr.dotted_string))
msg = 'Name attribute [{attr._name}, {attr.dotted_string}] is not allowed in subjectDN' # noqa
res = FAILURE if attr in subj_attrs else SUCCESS
checks.append((res, msg))

# check if all the mandatory attre are present
for attr in MANDATORY_ATTRS:
msg = ('Name attribute [%s, %s] must be present in subjectDN'
% (attr._name, attr.dotted_string))
msg = f'Name attribute [{attr._name}, {attr.dotted_string}] must be present in subjectDN' # noqa
res = FAILURE if attr not in subj_attrs else SUCCESS
checks.append((res, msg))

# check the name attribute value
for attr in subj:
msg = ('Value for name attribute [%s, %s] can not be empty'
% (attr.oid._name, attr.oid.dotted_string))
msg = f'Value for name attribute [{attr.oid._name}, {attr.oid.dotted_string}] can not be empty' # noqa
res = FAILURE if not attr.value else SUCCESS
checks.append((res, msg))

Expand All @@ -87,19 +84,16 @@ def subject_dn(subj: x509.Name, sector: str) -> List[Tuple[bool, str]]:
elif sector == 'private':
pattern = r'^(CF:IT-[a-zA-Z0-9]{16}|VATIT-\d{11})$'
else:
msg = 'Invalid sector (%s)' % sector
msg = f'Invalid sector ({sector})'
res = FAILURE
checks.append((res, msg))

msg = ('Value for name attribute [%s, %s] must match [%s] (now: %s)' # noqa
% (attr.oid._name, attr.oid.dotted_string, pattern,
value))
msg = f'Value for name attribute [{attr.oid._name}, {attr.oid.dotted_string}] must match [{pattern}] (now: {value})' # noqa
res = FAILURE if not re.match(pattern, value) else SUCCESS
checks.append((res, msg))

if attr.oid == x509.OID_COUNTRY_NAME:
msg = ('Value for name attribute [%s, %s] is not a valid country code (%s)' # noqa
% (attr.oid._name, attr.oid.dotted_string, value))
msg = f'Value for name attribute [{attr.oid._name}, {attr.oid.dotted_string}] is not a valid country code ({value})' # noqa
try:
res = FAILURE if not isinstance(countries.get(value), Country) else SUCCESS # noqa
checks.append((res, msg))
Expand Down
6 changes: 3 additions & 3 deletions spid_compliant_certificates/validator/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

def pem_to_der(cert_file: str) -> Tuple[bytes, str]:
if not os.path.exists(cert_file):
msg = 'File at %s not found' % cert_file
msg = f'File at {cert_file} not found'
return None, msg

lines = []
Expand All @@ -34,11 +34,11 @@ def pem_to_der(cert_file: str) -> Tuple[bytes, str]:
fp.close()

if ('-----BEGIN CERTIFICATE-----' not in lines[0]):
msg = 'Certificate at %s must be a PEM' % cert_file
msg = f'Certificate at {cert_file} must be a PEM'
return None, msg

if ('-----END CERTIFICATE-----' not in lines[len(lines)-1]):
msg = 'Certificate at %s must be a PEM' % cert_file
msg = f'Certificate at {cert_file} must be a PEM'
return None, msg

b64_data = ''.join([line[:-1] for line in lines[1:-1]])
Expand Down
9 changes: 4 additions & 5 deletions spid_compliant_certificates/validator/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

def _indent(txt: str, count=1) -> str:
i = ' '
return '%s%s' % (i * count, txt)
return f'{i * count}{txt}'


def _do_check(checks: List[Tuple[bool, str]], base_msg: str) -> bool:
Expand All @@ -46,9 +46,9 @@ def _do_check(checks: List[Tuple[bool, str]], base_msg: str) -> bool:
break

if is_success:
LOG.info('%s: success' % base_msg)
LOG.info(f'{base_msg}: success')
else:
LOG.error('%s: failure' % base_msg)
LOG.error(f'{base_msg}: failure')

for res, msg in checks:
if res is FAILURE:
Expand Down Expand Up @@ -108,6 +108,5 @@ def validate(crt_file: str, sector: str) -> None:

for result in results:
if not result:
msg = ('The certificate %s does not match %s sector specifications'
% (crt_file, sector))
msg = f'The certificate {crt_file} does not match {sector} sector specifications' # noqa
raise Exception(msg)

0 comments on commit 0ba87db

Please sign in to comment.