Compare commits

..

2 Commits

Author SHA1 Message Date
Frédéric Tronel
0d772f59de Improve display of help and list certificate. 2025-12-30 11:02:43 +01:00
Frédéric Tronel
9f98cd1e70 Add a command to create a self-signed certificate. 2025-12-30 10:57:46 +01:00

View File

@@ -41,6 +41,7 @@ from cryptography import x509
from cryptography.hazmat.primitives.serialization import Encoding from cryptography.hazmat.primitives.serialization import Encoding
from dateutil.parser import parse from dateutil.parser import parse
from typeguard import typechecked from typeguard import typechecked
from datetime import datetime, timedelta
import requests import requests
import coloredlogs import coloredlogs
@@ -344,6 +345,40 @@ def install_certificate(hostname: str, verify: bool, username: str, password: st
logger.info('Certificate successfully installed.') logger.info('Certificate successfully installed.')
@typechecked
def self_signed(hostname:str, verify:bool, username: str, password: str, bearer=None) -> None:
logger = logging.getLogger(__name__)
base_url = f'https://{hostname}'
if bearer is None:
bearer = get_bearer(hostname, verify, username, password)
now = datetime.now()
end = now + timedelta(days=365)
end = end.strftime('%Y-%m-%dT%H:%M:%S.000Z')
url = base_url+'/cdm/certificate/v1/certificates/selfSignedCertificate'
certificate = {"version":"1.1.0","signatureAlgorithm":"sha256WithRsa",
"subjectAlternativeNameList":[hostname], "privateKeyExportable": False,
"links":[{"rel":"certificateConstraints",
"href":"/cdm/certificate/v1/certificates/selfSignedCertificate/constraints",
"hints":None}],
"certificateAttributes":{"commonName":hostname},
"keyInfo":{"keyType":"rsa","keyStrength":"bits2048"},
"validity":{"toDate":end},"state":"processing"}
headers = { 'Authorization': f'Bearer {bearer}' }
r = requests.patch(url, headers=headers, data=json.dumps(certificate), verify=verify,
timeout=10)
if r.status_code != 204:
logger.error('Impossible to create a self-signed certificate. Error code: %d',
r.status_code)
sys.exit(-1)
logger.info('Self-signed certificate created successfully.')
@typechecked @typechecked
def get_certificates(hostname:str, verify:bool, username: str, password: str, def get_certificates(hostname:str, verify:bool, username: str, password: str,
@@ -496,13 +531,15 @@ def main():
subparsers = parser.add_subparsers(dest='command', required=True, help='command help') subparsers = parser.add_subparsers(dest='command', required=True, help='command help')
subparsers.add_parser('list', help='List certificates') subparsers.add_parser('list', help='List certificates.')
parser_delete = subparsers.add_parser('del', help='Delete a certificate') subparsers.add_parser('self', help='Create a self-signed certificate.')
parser_delete = subparsers.add_parser('del', help='Delete a certificate.')
parser_delete.add_argument("-#", "--number", dest='certid', required=True, type=int, parser_delete.add_argument("-#", "--number", dest='certid', required=True, type=int,
help="Certificate number as given by list command.") help="Certificate number as given by list command.")
parser_create_csr = subparsers.add_parser('csr', help='Create CSR') parser_create_csr = subparsers.add_parser('csr', help='Create a certificate signing request.')
parser_create_csr.add_argument("-C", "--country", dest='country', required=False, default='US', parser_create_csr.add_argument("-C", "--country", dest='country', required=False, default='US',
help="Country.") help="Country.")
parser_create_csr.add_argument("-s", "--state", dest='state', required=False, help="State.") parser_create_csr.add_argument("-s", "--state", dest='state', required=False, help="State.")
@@ -514,7 +551,7 @@ def main():
parser_create_csr.add_argument("-o", "--output", dest='output', required=False, default=None, parser_create_csr.add_argument("-o", "--output", dest='output', required=False, default=None,
help="Output file.") help="Output file.")
parser_install_certificate = subparsers.add_parser('pem', help='Install certificate') parser_install_certificate = subparsers.add_parser('pem', help='Install a certificate.')
parser_install_certificate.add_argument("-i", "--input", dest='input', required=True, parser_install_certificate.add_argument("-i", "--input", dest='input', required=True,
default=None, help="Input file.") default=None, help="Input file.")
@@ -602,8 +639,8 @@ def main():
subject = cert.get('subject') subject = cert.get('subject')
issuer = cert.get('issuer') issuer = cert.get('issuer')
validity = cert.get('validity') validity = cert.get('validity')
begin = parse(validity.get('fromDate')) begin = parse(validity.get('fromDate')).strftime('%Y-%m-%d (%H:%M)')
end = parse(validity.get('toDate')) end = parse(validity.get('toDate')).strftime('%Y-%m-%d (%H:%M)')
print(f'{certid} - {subject} issued by {issuer}. From: {begin} to {end}') print(f'{certid} - {subject} issued by {issuer}. From: {begin} to {end}')
case 'del': case 'del':
bearer = get_bearer(hostname=args.hostname, verify=args.verify, username=args.username, bearer = get_bearer(hostname=args.hostname, verify=args.verify, username=args.username,
@@ -624,6 +661,9 @@ def main():
case 'pem': case 'pem':
install_certificate(hostname=args.hostname, verify=args.verify, username=args.username, install_certificate(hostname=args.hostname, verify=args.verify, username=args.username,
password=args.password, filename=args.input) password=args.password, filename=args.input)
case 'self':
self_signed(hostname=args.hostname, verify=args.verify, username=args.username,
password=args.password)
case _: case _:
logger.error('Unknown command: %s', args.command) logger.error('Unknown command: %s', args.command)
sys.exit(-1) sys.exit(-1)