Skip to content

Commit

Permalink
Adopt Black code formatting (#126)
Browse files Browse the repository at this point in the history
* Use Black formatter

* Fail CI/CD if source code is not formatted correctly

* Do format check first

* Revert back to Black after CI/CD test

* Clean up serverauth CertificateType enum

* Update CHANGELOG, add README blurb about Black format
  • Loading branch information
CBonnell authored Oct 23, 2024
1 parent 356adc6 commit 991808e
Show file tree
Hide file tree
Showing 129 changed files with 6,828 additions and 4,452 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/build_and_publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,15 @@ env:
IMAGE_NAME: ${{ github.repository }}

jobs:
test_source_format:
name: Test source code against Black formatter
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: psf/black@stable

build_wheel:
needs: [test_source_format]
name: Build pure-Python wheel and source distribution
runs-on: ubuntu-latest
steps:
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

All notable changes to this project from version 0.9.3 onwards are documented in this file.

## 0.12.3 - 2024-10-23

### New features/enhancements

- Reformat codebase to use [Black](https://github.com/psf/black) (#125)

## 0.12.2 - 2024-10-14

### Fixes
Expand Down
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
[![Python Versions](https://img.shields.io/pypi/pyversions/pkilint)](https://pypi.org/project/pkilint/)
[![Build status](https://github.com/digicert/pkilint/actions/workflows/build_and_publish.yml/badge.svg)](https://github.com/digicert/pkilint/actions/workflows/build_and_publish.yml)
[![GitHub license](https://img.shields.io/pypi/l/pkilint)](https://raw.githubusercontent.com/digicert/pkilint/main/LICENSE)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)

pkilint is a linting framework for documents that are encoded using ASN.1. pkilint is designed to
be a highly extensible toolbox to quickly create linters for a variety of ASN.1 structure/"document" types to check for compliance with
Expand Down Expand Up @@ -180,7 +181,7 @@ This tool lints end-entity S/MIME certificates against the
The `lint` sub-command requires that the user provide the certificate type/profile of the certificate so that the appropriate
validations are performed. There are three options:
1. Explicitly specify the type of S/MIME certificate using the `-t`/`--type` option. This may be useful when linting S/MIME certificates where the policy OIDs in the certificate do not map to a S/MIME validation level and generation.
1. Explicitly specify the type of S/MIME certificate using the `-t`/`--type` option. This may be useful when linting S/MIME certificates where the policy OIDs in the certificate do not map to an S/MIME validation level and generation.
2. Have the linter detect the type of certificate using the `-d`/`--detect` option. In this case, the linter will determine the validation level and generation using the policy OIDs included in the certificate. If a reserved CA/Browser Forum policy OID is found, then the corresponding validation level and generation are used. If no such reserved OIDs are found, then the optional mapping file (see below) is used. If no OIDs in the mapping file are found, then the tool exits with an error.
3. Have the linter detect the type of certificate using the `-g`/`--guess` option. This option uses the same identification procedure as the `--detect` option, with one major difference. Instead of exiting with an error upon being unable to find an appropriate policy OID, this option instead directs the linter to use heuristics to determine the validation level and generation.
Expand Down Expand Up @@ -417,12 +418,15 @@ Once the REST API server has been started, documentation will be available on th
## Bugs?
If you find a bug or other issue with pkilint, please create a Github issue.
If you find a bug or other issue with pkilint, please create a GitHub issue.
## Contributing
As we intend for this project to be an ecosystem resource, we welcome contributions. It is preferred that proposals for new
features be filed as Github issues so that design decisions, etc. can be discussed prior to submitting a pull request.
features be filed as GitHub issues so that design decisions, etc. can be discussed prior to submitting a pull request.
This project uses [Black](https://github.com/psf/black) code formatter. The CI/CD pipeline checks for compliance with
this format, so please ensure that any code contributions follow this format.
## Acknowledgements
Expand Down
2 changes: 1 addition & 1 deletion VERSION.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.12.2
0.12.3
8 changes: 4 additions & 4 deletions docker/entrypoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,22 @@

def main():
if len(sys.argv) < 2:
print('Executable not specified', file=sys.stderr)
print("Executable not specified", file=sys.stderr)

return 1

cmd = sys.argv[1]
args = sys.argv[2:]

try:
module = importlib.import_module(f'pkilint.bin.{cmd}')
module = importlib.import_module(f"pkilint.bin.{cmd}")

main_func = getattr(module, 'main')
main_func = getattr(module, "main")
except (ImportError, AttributeError):
os.execvp(cmd, [cmd] + args)

return main_func(args)


if __name__ == '__main__':
if __name__ == "__main__":
sys.exit(main())
13 changes: 8 additions & 5 deletions pkilint/adobe/adobe_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,22 @@
class AdobeTimestampValidator(validation.Validator):
VALIDATION_INVALID_GENERALNAME_TYPE = validation.ValidationFinding(
validation.ValidationFindingSeverity.ERROR,
'adbe.invalid_timestamp_location_type'
"adbe.invalid_timestamp_location_type",
)

def __init__(self):
super().__init__(validations=[self.VALIDATION_INVALID_GENERALNAME_TYPE], pdu_class=asn1.AdobeTimestamp)
super().__init__(
validations=[self.VALIDATION_INVALID_GENERALNAME_TYPE],
pdu_class=asn1.AdobeTimestamp,
)

def validate(self, node):
gn = node.children['location']
gn = node.children["location"]

gn_type, _ = gn.child

if gn_type != 'uniformResourceIdentifier':
if gn_type != "uniformResourceIdentifier":
raise validation.ValidationFindingEncountered(
self.VALIDATION_INVALID_GENERALNAME_TYPE,
f'Invalid Adobe timestamp location type: {gn_type}'
f"Invalid Adobe timestamp location type: {gn_type}",
)
13 changes: 7 additions & 6 deletions pkilint/adobe/asn1/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from pyasn1_alt_modules import rfc5280


_ADOBE_X509_OID_ARC = univ.ObjectIdentifier('1.2.840.113583.1.1.9')
_ADOBE_X509_OID_ARC = univ.ObjectIdentifier("1.2.840.113583.1.1.9")


id_adobe_timestamp = univ.ObjectIdentifier(_ADOBE_X509_OID_ARC.asTuple() + (1,))
Expand All @@ -11,8 +11,9 @@
class AdobeExtensionVersion(univ.Integer):
pass


AdobeExtensionVersion.componentType = namedval.NamedValues(
('v1', 1),
("v1", 1),
)


Expand All @@ -21,9 +22,9 @@ class AdobeTimestamp(univ.Sequence):


AdobeTimestamp.componentType = namedtype.NamedTypes(
namedtype.NamedType('version', AdobeExtensionVersion()),
namedtype.NamedType('location', rfc5280.GeneralName()),
namedtype.DefaultedNamedType('requiresAuth', univ.Boolean().subtype(value=False))
namedtype.NamedType("version", AdobeExtensionVersion()),
namedtype.NamedType("location", rfc5280.GeneralName()),
namedtype.DefaultedNamedType("requiresAuth", univ.Boolean().subtype(value=False)),
)


Expand All @@ -35,7 +36,7 @@ class AdobeArchiveRevInfo(univ.Sequence):


AdobeArchiveRevInfo.componentType = namedtype.NamedTypes(
namedtype.NamedType('version', AdobeExtensionVersion())
namedtype.NamedType("version", AdobeExtensionVersion())
)


Expand Down
95 changes: 60 additions & 35 deletions pkilint/bin/lint_cabf_serverauth_cert.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
from pkilint.cabf.serverauth import serverauth_constants
from pkilint.pkix import certificate

_CERTIFICATE_TYPE_OPTIONS = [str(t).replace('_', '-') for t in serverauth_constants.CertificateType]
_CERTIFICATE_TYPE_OPTIONS = [
str(t).replace("_", "-") for t in serverauth_constants.CertificateType
]


class ServerauthCertificateTypeAction(argparse.Action):
Expand All @@ -23,61 +25,82 @@ def __call__(self, parser, namespace, values, option_string=None):

def main(cli_args=None) -> int:
parser = argparse.ArgumentParser(
description=f'CA/Browser Forum TLS Baseline Requirements v{serverauth_constants.BR_VERSION} Certificate Linter'
description=f"CA/Browser Forum TLS Baseline Requirements v{serverauth_constants.BR_VERSION} Certificate Linter"
)

subparsers = parser.add_subparsers(dest='command', required=True)
subparsers = parser.add_subparsers(dest="command", required=True)

validations_parser = subparsers.add_parser('validations',
help='Output the set of validations which this linter performs')
validations_parser.add_argument('-t', '--type', required=True,
type=str.upper,
action=ServerauthCertificateTypeAction,
help='The type of certificate',
choices=_CERTIFICATE_TYPE_OPTIONS)
validations_parser = subparsers.add_parser(
"validations", help="Output the set of validations which this linter performs"
)
validations_parser.add_argument(
"-t",
"--type",
required=True,
type=str.upper,
action=ServerauthCertificateTypeAction,
help="The type of certificate",
choices=_CERTIFICATE_TYPE_OPTIONS,
)

lint_parser = subparsers.add_parser('lint', help='Lint the specified certificate')
lint_parser = subparsers.add_parser("lint", help="Lint the specified certificate")

detect_options_group = lint_parser.add_mutually_exclusive_group(required=True)
detect_options_group.add_argument('-d', '--detect', action='store_true',
help='Detect the type of certificate from reserved CA/B Forum policy '
'OID, EKU(s), name constraints, and basic constraints.')
detect_options_group.add_argument('-t', '--type',
type=str.upper,
action=ServerauthCertificateTypeAction,
help='The type of certificate',
choices=_CERTIFICATE_TYPE_OPTIONS)
lint_parser.add_argument('-o', '--output', action='store_true',
help='Output the type of certificate to standard error. This option may be '
'useful when using the --detect option.')
lint_parser.add_argument('-r', '--report-all', action='store_true', help='Report all findings without filtering '
'any PKIX findings that are superseded by CA/Browser Forum requirements')
detect_options_group.add_argument(
"-d",
"--detect",
action="store_true",
help="Detect the type of certificate from reserved CA/B Forum policy "
"OID, EKU(s), name constraints, and basic constraints.",
)
detect_options_group.add_argument(
"-t",
"--type",
type=str.upper,
action=ServerauthCertificateTypeAction,
help="The type of certificate",
choices=_CERTIFICATE_TYPE_OPTIONS,
)
lint_parser.add_argument(
"-o",
"--output",
action="store_true",
help="Output the type of certificate to standard error. This option may be "
"useful when using the --detect option.",
)
lint_parser.add_argument(
"-r",
"--report-all",
action="store_true",
help="Report all findings without filtering "
"any PKIX findings that are superseded by CA/Browser Forum requirements",
)

cli_util.add_certificate_validity_period_start_arg(lint_parser)

cli_util.add_standard_args(lint_parser)
lint_parser.add_argument('file', type=argparse.FileType('rb'),
help='The certificate to lint'
)
lint_parser.add_argument(
"file", type=argparse.FileType("rb"), help="The certificate to lint"
)

args = parser.parse_args(cli_args)

if args.command == 'validations':
if args.command == "validations":
doc_validator = certificate.create_pkix_certificate_validator_container(
serverauth.create_decoding_validators(),
serverauth.create_validators(args.type)
serverauth.create_validators(args.type),
)

print(report.report_included_validations(doc_validator))

return 0
else:
try:
cert = loader.RFC5280CertificateDocumentLoader().get_file_loader_func(args.document_format)(
args.file, args.file.name
)
cert = loader.RFC5280CertificateDocumentLoader().get_file_loader_func(
args.document_format
)(args.file, args.file.name)
except ValueError as e:
print(f'Failed to load certificate: {e}', file=sys.stderr)
print(f"Failed to load certificate: {e}", file=sys.stderr)
return 1

if args.type:
Expand All @@ -90,7 +113,7 @@ def main(cli_args=None) -> int:

doc_validator = certificate.create_pkix_certificate_validator_container(
serverauth.create_decoding_validators(),
serverauth.create_validators(certificate_type, args.validity_period_start)
serverauth.create_validators(certificate_type, args.validity_period_start),
)

results = doc_validator.validate(cert.root)
Expand All @@ -102,7 +125,9 @@ def main(cli_args=None) -> int:

print(args.format(results, args.severity))

return cli_util.clamp_exit_code(report.get_findings_count(results, args.severity))
return cli_util.clamp_exit_code(
report.get_findings_count(results, args.severity)
)


if __name__ == "__main__":
Expand Down
Loading

0 comments on commit 991808e

Please sign in to comment.