mirror of
https://github.com/trailofbits/algo.git
synced 2025-06-05 06:33:56 +02:00
Ca certificate name constraints (#1675)
* X.509 Name Constraints * nameConstraints to a random generated uuid * Second level domain * nameConstraints fixes * critical in nameConstraints lost after last refactoring
This commit is contained in:
parent
0e57da8237
commit
0efa4eaf91
7 changed files with 60 additions and 17 deletions
|
@ -4,6 +4,7 @@
|
||||||
# Every device must have a unique username.
|
# Every device must have a unique username.
|
||||||
# You can generate up to 250 users at one time.
|
# You can generate up to 250 users at one time.
|
||||||
# Usernames with leading 0's or containing only numbers should be escaped in double quotes, e.g. "000dan" or "123".
|
# Usernames with leading 0's or containing only numbers should be escaped in double quotes, e.g. "000dan" or "123".
|
||||||
|
# Emails are not allowed
|
||||||
users:
|
users:
|
||||||
- phone
|
- phone
|
||||||
- laptop
|
- laptop
|
||||||
|
|
|
@ -10,9 +10,25 @@ algo_ondemand_wifi_exclude: '_null'
|
||||||
algo_dns_adblocking: false
|
algo_dns_adblocking: false
|
||||||
ipv6_support: false
|
ipv6_support: false
|
||||||
dns_encryption: true
|
dns_encryption: true
|
||||||
domain: false
|
openssl_constraint_random_id: "{{ IP_subject_alt_name | to_uuid }}.algo"
|
||||||
subjectAltName_IP: "{{ 'DNS:' if IP_subject_alt_name|regex_search('[a-z]') else 'IP:' }}{{ IP_subject_alt_name }}"
|
subjectAltName_type: "{{ 'DNS' if IP_subject_alt_name|regex_search('[a-z]') else 'IP' }}"
|
||||||
subjectAltName_USER: "{% if '@' in item %}email:{{ item }}{% else %}DNS:{{ item }}{% endif %}"
|
subjectAltName: >-
|
||||||
|
{{ subjectAltName_type }}:{{ IP_subject_alt_name }}
|
||||||
|
{%- if ipv6_support -%},IP:{{ ansible_default_ipv6['address'] }}{%- endif -%}
|
||||||
|
subjectAltName_USER: "email:{{ item }}@{{ openssl_constraint_random_id }}"
|
||||||
|
nameConstraints: >-
|
||||||
|
critical,permitted;{{ subjectAltName_type }}:{{ IP_subject_alt_name }}{{- '/255.255.255.255' if subjectAltName_type == 'IP' else '' -}}
|
||||||
|
{%- if subjectAltName_type == 'IP' -%}
|
||||||
|
,permitted;DNS:{{ openssl_constraint_random_id }}
|
||||||
|
{%- else -%}
|
||||||
|
,excluded;IP:0.0.0.0/0.0.0.0
|
||||||
|
{%- endif -%}
|
||||||
|
,permitted;email:{{ openssl_constraint_random_id }}
|
||||||
|
{%- if ipv6_support -%}
|
||||||
|
,permitted;IP:{{ ansible_default_ipv6['address'] }}/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
|
||||||
|
{%- else -%}
|
||||||
|
,excluded;IP:0:0:0:0:0:0:0:0/0:0:0:0:0:0:0:0
|
||||||
|
{%- endif -%}
|
||||||
openssl_bin: openssl
|
openssl_bin: openssl
|
||||||
strongswan_enabled_plugins:
|
strongswan_enabled_plugins:
|
||||||
- aes
|
- aes
|
||||||
|
|
|
@ -1,13 +1,5 @@
|
||||||
---
|
---
|
||||||
- block:
|
- block:
|
||||||
- name: Set subjectAltName as a fact
|
|
||||||
set_fact:
|
|
||||||
subjectAltName: >-
|
|
||||||
{{ subjectAltName_IP }}
|
|
||||||
{%- if ipv6_support -%},IP:{{ ansible_default_ipv6['address'] }}{%- endif -%}
|
|
||||||
{%- if domain and subjectAltName_DNS -%},DNS:{{ subjectAltName_DNS }}{%- endif -%}
|
|
||||||
tags: always
|
|
||||||
|
|
||||||
- debug: var=subjectAltName
|
- debug: var=subjectAltName
|
||||||
|
|
||||||
- name: Ensure the pki directory does not exist
|
- name: Ensure the pki directory does not exist
|
||||||
|
@ -132,6 +124,30 @@
|
||||||
executable: bash
|
executable: bash
|
||||||
with_items: "{{ users }}"
|
with_items: "{{ users }}"
|
||||||
|
|
||||||
|
- name: Build the tests pair
|
||||||
|
shell: >
|
||||||
|
umask 077;
|
||||||
|
{{ openssl_bin }} req -utf8 -new
|
||||||
|
-newkey ec:ecparams/secp384r1.pem
|
||||||
|
-config <(cat openssl.cnf <(printf "[basic_exts]\nsubjectAltName=DNS:google-algo-test-pair.com"))
|
||||||
|
-keyout private/google-algo-test-pair.com.key
|
||||||
|
-out reqs/google-algo-test-pair.com.req -nodes
|
||||||
|
-passin pass:"{{ CA_password }}"
|
||||||
|
-subj "/CN=google-algo-test-pair.com" -batch &&
|
||||||
|
{{ openssl_bin }} ca -utf8
|
||||||
|
-in reqs/google-algo-test-pair.com.req
|
||||||
|
-out certs/google-algo-test-pair.com.crt
|
||||||
|
-config <(cat openssl.cnf <(printf "[basic_exts]\nsubjectAltName=DNS:google-algo-test-pair.com"))
|
||||||
|
-days 3650 -batch
|
||||||
|
-passin pass:"{{ CA_password }}"
|
||||||
|
-subj "/CN=google-algo-test-pair.com" &&
|
||||||
|
touch certs/google-algo-test-pair.com_crt_generated
|
||||||
|
args:
|
||||||
|
chdir: "{{ ipsec_pki_path }}"
|
||||||
|
creates: certs/google-algo-test-pair.com_crt_generated
|
||||||
|
executable: bash
|
||||||
|
when: tests|default(false)|bool
|
||||||
|
|
||||||
- name: Build openssh public keys
|
- name: Build openssh public keys
|
||||||
openssl_publickey:
|
openssl_publickey:
|
||||||
path: "{{ ipsec_pki_path }}/public/{{ item }}.pub"
|
path: "{{ ipsec_pki_path }}/public/{{ item }}.pub"
|
||||||
|
@ -201,7 +217,7 @@
|
||||||
chdir: "{{ ipsec_pki_path }}"
|
chdir: "{{ ipsec_pki_path }}"
|
||||||
creates: crl/{{ item }}.crt
|
creates: crl/{{ item }}.crt
|
||||||
executable: bash
|
executable: bash
|
||||||
when: item not in users
|
when: item.split('@')[0] not in users
|
||||||
with_items: "{{ valid_certs.stdout_lines }}"
|
with_items: "{{ valid_certs.stdout_lines }}"
|
||||||
|
|
||||||
- name: Genereate new CRL file
|
- name: Genereate new CRL file
|
||||||
|
|
|
@ -358,7 +358,7 @@ charon {
|
||||||
x509 {
|
x509 {
|
||||||
|
|
||||||
# Discard certificates with unsupported or unknown critical extensions.
|
# Discard certificates with unsupported or unknown critical extensions.
|
||||||
# enforce_critical = yes
|
enforce_critical = no
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@
|
||||||
<integer>1440</integer>
|
<integer>1440</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>LocalIdentifier</key>
|
<key>LocalIdentifier</key>
|
||||||
<string>{{ item.0 }}</string>
|
<string>{{ item.0 }}@{{ openssl_constraint_random_id }}</string>
|
||||||
<key>PayloadCertificateUUID</key>
|
<key>PayloadCertificateUUID</key>
|
||||||
<string>{{ pkcs12_PayloadCertificateUUID }}</string>
|
<string>{{ pkcs12_PayloadCertificateUUID }}</string>
|
||||||
<key>CertificateType</key>
|
<key>CertificateType</key>
|
||||||
|
|
|
@ -119,9 +119,9 @@ keyUsage = digitalSignature, keyEncipherment
|
||||||
subjectKeyIdentifier=hash
|
subjectKeyIdentifier=hash
|
||||||
authorityKeyIdentifier=keyid:always,issuer:always
|
authorityKeyIdentifier=keyid:always,issuer:always
|
||||||
|
|
||||||
# This could be marked critical, but it's nice to support reading by any
|
basicConstraints = critical,CA:true,pathlen:0
|
||||||
# broken clients who attempt to do so.
|
nameConstraints = {{ nameConstraints }}
|
||||||
basicConstraints = CA:true
|
|
||||||
|
|
||||||
# Limit key usage to CA tasks. If you really want to use the generated pair as
|
# Limit key usage to CA tasks. If you really want to use the generated pair as
|
||||||
# a self-signed cert, comment this out.
|
# a self-signed cert, comment this out.
|
||||||
|
|
|
@ -4,6 +4,16 @@ set -euxo pipefail
|
||||||
|
|
||||||
xmllint --noout ./configs/10.0.8.100/ipsec/apple/user1.mobileconfig
|
xmllint --noout ./configs/10.0.8.100/ipsec/apple/user1.mobileconfig
|
||||||
|
|
||||||
|
CA_CONSTRAINTS="$(openssl verify -verbose \
|
||||||
|
-CAfile ./configs/10.0.8.100/ipsec/.pki/cacert.pem \
|
||||||
|
./configs/10.0.8.100/ipsec/.pki/certs/google-algo-test-pair.com.crt 2>&1)" || true
|
||||||
|
|
||||||
|
echo "$CA_CONSTRAINTS" | grep "permitted subtree violation" >/dev/null && \
|
||||||
|
echo "Name Constraints test passed" || \
|
||||||
|
(echo "Name Constraints test failed" && exit 1)
|
||||||
|
|
||||||
|
echo "$CA_CONSTRAINTS"
|
||||||
|
|
||||||
ansible-playbook deploy_client.yml \
|
ansible-playbook deploy_client.yml \
|
||||||
-e client_ip=localhost \
|
-e client_ip=localhost \
|
||||||
-e vpn_user=desktop \
|
-e vpn_user=desktop \
|
||||||
|
|
Loading…
Add table
Reference in a new issue