diff options
| author | Ben Lipton <blipton@redhat.com> | 2016-07-05 14:19:35 -0400 |
|---|---|---|
| committer | Jan Cholasta <jcholast@redhat.com> | 2017-01-31 10:20:28 +0100 |
| commit | 10ef5947860f5098182b1f95c08c1158e2da15f9 (patch) | |
| tree | 360f7bb40f2eab2dcc2a1fa2c8460643c77524ec /install | |
| parent | 87400cdec1054971f50f90a0c63f18ab045f3833 (diff) | |
| download | freeipa-10ef5947860f5098182b1f95c08c1158e2da15f9.tar.gz freeipa-10ef5947860f5098182b1f95c08c1158e2da15f9.tar.xz freeipa-10ef5947860f5098182b1f95c08c1158e2da15f9.zip | |
csrgen: Add code to generate scripts that generate CSRs
Adds a library that uses jinja2 to format a script that, when run, will
build a CSR. Also adds a CLI command, 'cert-get-requestdata', that uses
this library and builds the script for a given principal. The rules are
read from json files in /usr/share/ipa/csr, but the rule provider is a
separate class so that it can be replaced easily.
https://fedorahosted.org/freeipa/ticket/4899
Reviewed-By: Jan Cholasta <jcholast@redhat.com>
Diffstat (limited to 'install')
| -rw-r--r-- | install/share/Makefile.am | 1 | ||||
| -rw-r--r-- | install/share/csr/templates/ipa_macros.tmpl | 42 | ||||
| -rw-r--r-- | install/share/csrgen/Makefile.am | 27 | ||||
| -rw-r--r-- | install/share/csrgen/templates/certutil_base.tmpl | 14 | ||||
| -rw-r--r-- | install/share/csrgen/templates/openssl_base.tmpl | 35 | ||||
| -rw-r--r-- | install/share/csrgen/templates/openssl_macros.tmpl | 29 |
6 files changed, 148 insertions, 0 deletions
diff --git a/install/share/Makefile.am b/install/share/Makefile.am index 10de84d08..715912d8b 100644 --- a/install/share/Makefile.am +++ b/install/share/Makefile.am @@ -2,6 +2,7 @@ NULL = SUBDIRS = \ advise \ + csrgen \ profiles \ schema.d \ $(NULL) diff --git a/install/share/csr/templates/ipa_macros.tmpl b/install/share/csr/templates/ipa_macros.tmpl new file mode 100644 index 000000000..e790d4eb5 --- /dev/null +++ b/install/share/csr/templates/ipa_macros.tmpl @@ -0,0 +1,42 @@ +{% set rendersyntax = {} %} + +{% set renderdata = {} %} + +{# Wrapper for syntax rules. We render the contents of the rule into a +variable, so that if we find that none of the contained data rules rendered we +can suppress the whole syntax rule. That is, a syntax rule is rendered either +if no data rules are specified (unusual) or if at least one of the data rules +rendered successfully. #} +{% macro syntaxrule() -%} +{% do rendersyntax.update(none=true, any=false) -%} +{% set contents -%} +{{ caller() -}} +{% endset -%} +{% if rendersyntax['none'] or rendersyntax['any'] -%} +{{ contents -}} +{% endif -%} +{% endmacro %} + +{# Wrapper for data rules. A data rule is rendered only when all of the data +fields it contains have data available. #} +{% macro datarule() -%} +{% do rendersyntax.update(none=false) -%} +{% do renderdata.update(all=true) -%} +{% set contents -%} +{{ caller() -}} +{% endset -%} +{% if renderdata['all'] -%} +{% do rendersyntax.update(any=true) -%} +{{ contents -}} +{% endif -%} +{% endmacro %} + +{# Wrapper for fields in data rules. If any value wrapped by this macro +produces an empty string, the entire data rule will be suppressed. #} +{% macro datafield(value) -%} +{% if value -%} +{{ value -}} +{% else -%} +{% do renderdata.update(all=false) -%} +{% endif -%} +{% endmacro %} diff --git a/install/share/csrgen/Makefile.am b/install/share/csrgen/Makefile.am new file mode 100644 index 000000000..7b718cca1 --- /dev/null +++ b/install/share/csrgen/Makefile.am @@ -0,0 +1,27 @@ +NULL = + +profiledir = $(IPA_DATA_DIR)/csrgen/profiles +profile_DATA = \ + $(NULL) + +ruledir = $(IPA_DATA_DIR)/csrgen/rules +rule_DATA = \ + $(NULL) + +templatedir = $(IPA_DATA_DIR)/csrgen/templates +template_DATA = \ + templates/certutil_base.tmpl \ + templates/openssl_base.tmpl \ + templates/openssl_macros.tmpl \ + templates/ipa_macros.tmpl \ + $(NULL) + +EXTRA_DIST = \ + $(profile_DATA) \ + $(rule_DATA) \ + $(template_DATA) \ + $(NULL) + +MAINTAINERCLEANFILES = \ + *~ \ + Makefile.in diff --git a/install/share/csrgen/templates/certutil_base.tmpl b/install/share/csrgen/templates/certutil_base.tmpl new file mode 100644 index 000000000..6c6425fc0 --- /dev/null +++ b/install/share/csrgen/templates/certutil_base.tmpl @@ -0,0 +1,14 @@ +{% raw -%} +{% import "ipa_macros.tmpl" as ipa -%} +{%- endraw %} +#!/bin/bash -e + +if [[ $# -lt 1 ]]; then +echo "Usage: $0 <outfile> [<any> <certutil> <args>]" +echo "Called as: $0 $@" +exit 1 +fi + +CSR="$1" +shift +certutil -R -a -z <(head -c 4096 /dev/urandom) -o "$CSR" {{ options|join(' ') }} "$@" diff --git a/install/share/csrgen/templates/openssl_base.tmpl b/install/share/csrgen/templates/openssl_base.tmpl new file mode 100644 index 000000000..597577bcd --- /dev/null +++ b/install/share/csrgen/templates/openssl_base.tmpl @@ -0,0 +1,35 @@ +{% raw -%} +{% import "openssl_macros.tmpl" as openssl -%} +{% import "ipa_macros.tmpl" as ipa -%} +{%- endraw %} +#!/bin/bash -e + +if [[ $# -ne 2 ]]; then +echo "Usage: $0 <outfile> <keyfile>" +echo "Called as: $0 $@" +exit 1 +fi + +CONFIG="$(mktemp)" +CSR="$1" +shift + +echo \ +{% raw %}{% filter quote %}{% endraw -%} +[ req ] +prompt = no +encrypt_key = no + +{{ parameters|join('\n') }} +{% raw %}{% set rendered_extensions -%}{% endraw %} +{{ extensions|join('\n') }} +{% raw -%} +{%- endset -%} +{% if rendered_extensions -%} +req_extensions = {% call openssl.section() %}{{ rendered_extensions }}{% endcall %} +{% endif %} +{{ openssl.openssl_sections|join('\n\n') }} +{% endfilter %}{%- endraw %} > "$CONFIG" + +openssl req -new -config "$CONFIG" -out "$CSR" -key $1 +rm "$CONFIG" diff --git a/install/share/csrgen/templates/openssl_macros.tmpl b/install/share/csrgen/templates/openssl_macros.tmpl new file mode 100644 index 000000000..d31b8fef5 --- /dev/null +++ b/install/share/csrgen/templates/openssl_macros.tmpl @@ -0,0 +1,29 @@ +{# List containing rendered sections to be included at end #} +{% set openssl_sections = [] %} + +{# +List containing one entry for each section name allocated. Because of +scoping rules, we need to use a list so that it can be a "per-render global" +that gets updated in place. Real globals are shared by all templates with the +same environment, and variables defined in the macro don't persist after the +macro invocation ends. +#} +{% set openssl_section_num = [] %} + +{% macro section() -%} +{% set name -%} +sec{{ openssl_section_num|length -}} +{% endset -%} +{% do openssl_section_num.append('') -%} +{% set contents %}{{ caller() }}{% endset -%} +{% if contents -%} +{% set sectiondata = formatsection(name, contents) -%} +{% do openssl_sections.append(sectiondata) -%} +{% endif -%} +{{ name -}} +{% endmacro %} + +{% macro formatsection(name, contents) -%} +[ {{ name }} ] +{{ contents -}} +{% endmacro %} |
