| |
@@ -0,0 +1,144 @@
|
| |
+
|
| |
+ from lib389.nss_ssl import NssSsl, CERT_NAME, CA_NAME
|
| |
+ from lib389.cli_base import _warn
|
| |
+
|
| |
+ def show_servercert(inst, log, args):
|
| |
+ tls = NssSsl(dirsrv=inst)
|
| |
+ log.info(tls.display_cert_details(CERT_NAME))
|
| |
+
|
| |
+ def list_client_cas(inst, log, args):
|
| |
+ tls = NssSsl(dirsrv=inst)
|
| |
+ # This turns an array of [('CA', 'C,,')]
|
| |
+ for c in tls.list_client_ca_certs():
|
| |
+ log.info(c[0])
|
| |
+
|
| |
+ def list_cas(inst, log, args):
|
| |
+ tls = NssSsl(dirsrv=inst)
|
| |
+ # This turns an array of [('CA', 'C,,')]
|
| |
+ for c in tls.list_ca_certs():
|
| |
+ log.info(c[0])
|
| |
+
|
| |
+ def show_cert(inst, log, args):
|
| |
+ tls = NssSsl(dirsrv=inst)
|
| |
+ nickname = args.nickname
|
| |
+ log.info(tls.display_cert_details(nickname))
|
| |
+
|
| |
+ def import_client_ca(inst, log, args):
|
| |
+ tls = NssSsl(dirsrv=inst)
|
| |
+ cert_path = args.cert_path
|
| |
+ nickname = args.nickname
|
| |
+ if nickname.lower() == CERT_NAME.lower() or nickname.lower() == CA_NAME.lower():
|
| |
+ log.error("You may not import a CA with the nickname %s or %s" % (CERT_NAME, CA_NAME))
|
| |
+ return
|
| |
+ tls.add_cert(nickname=nickname, input_file=cert_path)
|
| |
+ tls.edit_cert_trust(nickname, "T,,")
|
| |
+
|
| |
+ def import_ca(inst, log, args):
|
| |
+ tls = NssSsl(dirsrv=inst)
|
| |
+ cert_path = args.cert_path
|
| |
+ nickname = args.nickname
|
| |
+ if nickname.lower() == CERT_NAME.lower() or nickname.lower() == CA_NAME.lower():
|
| |
+ log.error("You may not import a CA with the nickname %s or %s" % (CERT_NAME, CA_NAME))
|
| |
+ return
|
| |
+ tls.add_cert(nickname=nickname, input_file=cert_path)
|
| |
+ tls.edit_cert_trust(nickname, "C,,")
|
| |
+
|
| |
+ def import_key_cert_pair(inst, log, args):
|
| |
+ tls = NssSsl(dirsrv=inst)
|
| |
+ key_path = args.key_path
|
| |
+ cert_path = args.cert_path
|
| |
+ tls.add_server_key_and_cert(key_path, cert_path)
|
| |
+
|
| |
+ def generate_key_csr(inst, log, args):
|
| |
+ tls = NssSsl(dirsrv=inst)
|
| |
+ alt_names = args.alt_names
|
| |
+ subject = args.subject
|
| |
+ out_path = tls.create_rsa_key_and_csr(alt_names, subject)
|
| |
+ log.info(out_path)
|
| |
+
|
| |
+ def import_server_cert(inst, log, args):
|
| |
+ tls = NssSsl(dirsrv=inst)
|
| |
+ cert_path = args.cert_path
|
| |
+ tls.import_rsa_crt(crt=cert_path)
|
| |
+
|
| |
+ def remove_cert(inst, log, args, warn=True):
|
| |
+ tls = NssSsl(dirsrv=inst)
|
| |
+ nickname = args.nickname
|
| |
+ if warn:
|
| |
+ _warn(nickname, msg="Deleting certificate %s" % nickname)
|
| |
+ tls.del_cert(nickname)
|
| |
+
|
| |
+
|
| |
+ def create_parser(subparsers):
|
| |
+ tls_parser = subparsers.add_parser('tls', help="Manage TLS certificates")
|
| |
+
|
| |
+ subcommands = tls_parser.add_subparsers(help='action')
|
| |
+
|
| |
+ list_ca_parser = subcommands.add_parser('list-ca', help='list server certificate authorities including intermediates')
|
| |
+ list_ca_parser.set_defaults(func=list_cas)
|
| |
+
|
| |
+ list_client_ca_parser = subcommands.add_parser('list-client-ca', help='list client certificate authorities including intermediates')
|
| |
+ list_client_ca_parser.set_defaults(func=list_client_cas)
|
| |
+
|
| |
+ show_servercert_parser = subcommands.add_parser('show-server-cert', help='Show the active server certificate that clients will see and verify')
|
| |
+ show_servercert_parser.set_defaults(func=show_servercert)
|
| |
+
|
| |
+ show_cert_parser = subcommands.add_parser('show-cert', help='Show a certificate\'s details referenced by it\'s nickname. This is analogous to certutil -L -d <path> -n <nickname>')
|
| |
+ show_cert_parser.add_argument('nickname', help="The nickname (friendly name) of the certificate to display")
|
| |
+ show_cert_parser.set_defaults(func=show_cert)
|
| |
+
|
| |
+ generate_server_cert_csr_parser = subcommands.add_parser(
|
| |
+ 'generate-server-cert-csr',
|
| |
+ help="Generate a Server-Cert certificate signing request - the csr is then submitted to a CA for verification, and when signed you import with import-ca and import-server-cert"
|
| |
+ )
|
| |
+ generate_server_cert_csr_parser.add_argument('--subject', '-s',
|
| |
+ default=None,
|
| |
+ help="Certificate Subject field to use")
|
| |
+ generate_server_cert_csr_parser.add_argument('alt_names', nargs='*',
|
| |
+ help="Certificate requests subject alternative names. These are auto-detected if not provided")
|
| |
+ generate_server_cert_csr_parser.set_defaults(func=generate_key_csr)
|
| |
+
|
| |
+ import_client_ca_parser = subcommands.add_parser(
|
| |
+ 'import-client-ca',
|
| |
+ help="Import a CA trusted to issue user (client) certificates. This is part of how client certificate authentication functions."
|
| |
+ )
|
| |
+ import_client_ca_parser.add_argument('cert_path',
|
| |
+ help="The path to the x509 cert to import as a client trust root")
|
| |
+ import_client_ca_parser.add_argument('nickname', help="The name of the certificate once imported")
|
| |
+ import_client_ca_parser.set_defaults(func=import_client_ca)
|
| |
+
|
| |
+ import_ca_parser = subcommands.add_parser(
|
| |
+ 'import-ca',
|
| |
+ help="Import a CA or intermediate CA for signing this servers certificates (aka Server-Cert). You should import all the CA's in the chain as required."
|
| |
+ )
|
| |
+ import_ca_parser.add_argument('cert_path',
|
| |
+ help="The path to the x509 cert to import as a server CA")
|
| |
+ import_ca_parser.add_argument('nickname', help="The name of the certificate once imported")
|
| |
+ import_ca_parser.set_defaults(func=import_ca)
|
| |
+
|
| |
+ import_server_cert_parser = subcommands.add_parser(
|
| |
+ 'import-server-cert',
|
| |
+ help="Import a new Server-Cert after the csr has been signed from a CA."
|
| |
+ )
|
| |
+ import_server_cert_parser.add_argument('cert_path',
|
| |
+ help="The path to the x509 cert to import as Server-Cert")
|
| |
+ import_server_cert_parser.set_defaults(func=import_server_cert)
|
| |
+
|
| |
+ import_server_key_cert_parser = subcommands.add_parser(
|
| |
+ 'import-server-key-cert',
|
| |
+ help="Import a new key and Server-Cert after having been signed from a CA. This is used if you have an external csr tool or a service like lets encrypt that generates PEM keys externally."
|
| |
+ )
|
| |
+ import_server_key_cert_parser.add_argument('cert_path',
|
| |
+ help="The path to the x509 cert to import as Server-Cert")
|
| |
+ import_server_key_cert_parser.add_argument('key_path',
|
| |
+ help="The path to the x509 key to import associated to Server-Cert")
|
| |
+ import_server_key_cert_parser.set_defaults(func=import_key_cert_pair)
|
| |
+
|
| |
+ remove_cert_parser = subcommands.add_parser(
|
| |
+ 'remove-cert',
|
| |
+ help="Delete a certificate from this database. This will remove it from acting as a CA, a client CA or the Server-Cert role."
|
| |
+ )
|
| |
+ remove_cert_parser.add_argument('nickname', help="The name of the certificate to delete")
|
| |
+ remove_cert_parser.set_defaults(func=remove_cert)
|
| |
+
|
| |
+
|
| |
NSSDB's are difficult and hard to use. They make the certificate experience with 389 poor. This is really highlighted with systems like lets encrypt and such where people are so used to PEM file management, the idea of using certificate databases goes against this.
This adds support tooling to make the certificate DB easier to interact with. It's not intended to replace certutil - but to wrap and make common operations simpler to approach and use.
https://pagure.io/389-ds-base/issue/50007