From 4c4813df377a13a3b14b6cb07471d603b8168e80 Mon Sep 17 00:00:00 2001 From: Henrik Holmboe Date: Mon, 3 Oct 2016 17:24:13 +0200 Subject: [PATCH] Add msUPN support --- README.md | 9 +++++++++ bin/certified-csr | 10 +++++++++- lib/certified.sh | 5 +++++ test.sh | 17 +++++++++++++++++ 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4882d8e..d558500 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,15 @@ certified CN="localhost" +"127.0.0.1" The [wiki](https://github.com/rcrowley/certified/wiki) further documents common usage patterns and how to use your CA with various browsers, operating systems, and programming languages. +Advanced topics +--------------- + +Generate a certificate with an UPN used by Microsoft. Note that `otherName` is case sensitive: + +```sh +certified CN="john.doe@example.com" +"otherName:msUPN;UTF8:john.doe@example.com" +``` + TODO ---- diff --git a/bin/certified-csr b/bin/certified-csr index 3388e02..c100ad6 100755 --- a/bin/certified-csr +++ b/bin/certified-csr @@ -27,6 +27,7 @@ set -e SAN_DNS="" SAN_IP="" +SAN_OTHERNAME="" while [ "$#" -gt 0 ] do case "$1" in @@ -60,6 +61,10 @@ do ST=*) ST="$(echo "$1" | cut -d"=" -f"2-")" shift;; +*) SAN="$(echo "$1" | cut -c"2-")" shift + # Only one otherName is supported + if is_othername "$SAN" + then SAN_OTHERNAME="$SAN" + fi if is_ip "$SAN" then SAN_IP="$SAN_IP $SAN" elif is_dns "$SAN" @@ -176,7 +181,10 @@ EOF then echo "keyUsage = critical, cRLSign, keyCertSign, nonRepudiation" else echo "keyUsage = critical, digitalSignature, keyEncipherment" fi - if [ "$SAN_DNS" -o "$SAN_IP" ] + # The otherName cannot be used in conjunction with other SANs + if [ "$SAN_OTHERNAME" ] + then echo "subjectAltName = $SAN_OTHERNAME" + elif [ "$SAN_DNS" -o "$SAN_IP" ] then echo "subjectAltName = @san" fi echo "subjectKeyIdentifier = hash" diff --git a/lib/certified.sh b/lib/certified.sh index 39bcd47..df8497a 100644 --- a/lib/certified.sh +++ b/lib/certified.sh @@ -35,6 +35,11 @@ if_echo() { fi } +# Return zero if the first argument is otherName. Return non-zero otherwise. +is_othername() { + echo "$1" | grep -E -q "otherName" +} + # Return zero if the first argument looks like a DNS name, including wildcards # and single labels. Return non-zero otherwise. is_dns() { diff --git a/test.sh b/test.sh index 68baa66..6de4d67 100644 --- a/test.sh +++ b/test.sh @@ -140,6 +140,23 @@ grep -q "DNS:example.com" openssl x509 -in "etc/ssl/certs/san.crt" -noout -text | grep -q "IP Address:127.0.0.1" +# Test that we can add msUPN SAN (OID 1.3.6.1.4.1.311.20.2.3). +certified CN="msUPN" +"otherName:msUPN;UTF8:john.doe@example.com" +openssl x509 -in "etc/ssl/certs/msupn.crt" -noout -text | +grep -q "othername:" +openssl x509 -in "etc/ssl/certs/msupn.crt" -outform der | +openssl asn1parse -inform der -i -strparse \ + `openssl x509 -in etc/ssl/certs/msupn.crt -outform der | \ + openssl asn1parse -inform der -i | \ + grep -A 1 "Subject Alternative Name" | \ + tail -1 | cut -f1 -d:` | tail -1 | \ +grep -q "john.doe@example.com" + +# Test that we can generate a certificate with an email Common Name +certified CN="john.doe@example.com" +"otherName:msUPN;UTF8:john.doe@example.com" +openssl x509 -in "etc/ssl/certs/john.doe@example.com.crt" -noout -text | + grep -q "Subject: CN=john.doe@example.com" + # Test that a valid DNS name as CN is added as a subject alternative name. certified CN="example.com" openssl x509 -in "etc/ssl/certs/example.com.crt" -noout -text |