From: Jouni Malinen Date: Fri, 25 Oct 2013 14:54:25 +0000 (+0300) Subject: OSU server: Add example scripts for Hotspot 2.0 PKI X-Git-Tag: hostap_2_2~405 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0b2c59e315a6d50e85efb80c1c05291e88fca44a;p=thirdparty%2Fhostap.git OSU server: Add example scripts for Hotspot 2.0 PKI These can be used to generate certificates for developer testing of the OSU protocol. Signed-off-by: Jouni Malinen --- diff --git a/hs20/server/ca/clean.sh b/hs20/server/ca/clean.sh new file mode 100755 index 000000000..c69a1f54c --- /dev/null +++ b/hs20/server/ca/clean.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +for i in server-client server server-revoked user ocsp; do + rm -f $i.csr $i.key $i.pem +done + +rm -f openssl.cnf.tmp +rm -r demoCA +rm -f ca.pem logo.asn1 logo.der server.der ocsp-server-cache.der +#rm -r rootCA diff --git a/hs20/server/ca/est-csrattrs.cnf b/hs20/server/ca/est-csrattrs.cnf new file mode 100644 index 000000000..b50ea00d0 --- /dev/null +++ b/hs20/server/ca/est-csrattrs.cnf @@ -0,0 +1,17 @@ +asn1 = SEQUENCE:attrs + +[attrs] +#oid1 = OID:challengePassword +attr1 = SEQUENCE:extreq +oid2 = OID:sha256WithRSAEncryption + +[extreq] +oid = OID:extensionRequest +vals = SET:extreqvals + +[extreqvals] + +oid1 = OID:macAddress +#oid2 = OID:imei +#oid3 = OID:meid +#oid4 = OID:DevId diff --git a/hs20/server/ca/est-csrattrs.sh b/hs20/server/ca/est-csrattrs.sh new file mode 100755 index 000000000..0b73a0408 --- /dev/null +++ b/hs20/server/ca/est-csrattrs.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +openssl asn1parse -genconf est-csrattrs.cnf -out est-csrattrs.der -oid hs20.oid +base64 est-csrattrs.der > est-attrs.b64 diff --git a/hs20/server/ca/hs20.oid b/hs20/server/ca/hs20.oid new file mode 100644 index 000000000..a829ff29b --- /dev/null +++ b/hs20/server/ca/hs20.oid @@ -0,0 +1,7 @@ +1.3.6.1.1.1.1.22 macAddress +1.2.840.113549.1.9.14 extensionRequest +1.3.6.1.4.1.40808.1.1.1 id-wfa-hotspot-friendlyName +1.3.6.1.4.1.40808.1.1.2 id-kp-HS2.0Auth +1.3.6.1.4.1.40808.1.1.3 imei +1.3.6.1.4.1.40808.1.1.4 meid +1.3.6.1.4.1.40808.1.1.5 DevId diff --git a/hs20/server/ca/ocsp-req.sh b/hs20/server/ca/ocsp-req.sh new file mode 100755 index 000000000..931a20696 --- /dev/null +++ b/hs20/server/ca/ocsp-req.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +for i in *.pem; do + echo "===[ $i ]===================" + openssl ocsp -text -CAfile ca.pem -verify_other demoCA/cacert.pem -trust_other -issuer demoCA/cacert.pem -cert $i -url http://localhost:8888/ + +# openssl ocsp -text -CAfile rootCA/cacert.pem -issuer demoCA/cacert.pem -cert $i -url http://localhost:8888/ + +# openssl ocsp -text -CAfile rootCA/cacert.pem -verify_other demoCA/cacert.pem -trust_other -issuer demoCA/cacert.pem -cert $i -url http://localhost:8888/ +# openssl ocsp -text -CAfile rootCA/cacert.pem -VAfile ca.pem -trust_other -issuer demoCA/cacert.pem -cert $i -url http://localhost:8888/ +done diff --git a/hs20/server/ca/ocsp-responder-ica.sh b/hs20/server/ca/ocsp-responder-ica.sh new file mode 100755 index 000000000..116c6e1c3 --- /dev/null +++ b/hs20/server/ca/ocsp-responder-ica.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +openssl ocsp -index demoCA/index.txt -port 8888 -nmin 5 -rsigner demoCA/cacert.pem -rkey demoCA/private/cakey-plain.pem -CA demoCA/cacert.pem -resp_no_certs -text diff --git a/hs20/server/ca/ocsp-responder.sh b/hs20/server/ca/ocsp-responder.sh new file mode 100755 index 000000000..8cebd7453 --- /dev/null +++ b/hs20/server/ca/ocsp-responder.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +openssl ocsp -index demoCA/index.txt -port 8888 -nmin 5 -rsigner ocsp.pem -rkey ocsp.key -CA demoCA/cacert.pem -text diff --git a/hs20/server/ca/ocsp-update-cache.sh b/hs20/server/ca/ocsp-update-cache.sh new file mode 100755 index 000000000..8ddef9b9c --- /dev/null +++ b/hs20/server/ca/ocsp-update-cache.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +openssl ocsp \ + -no_nonce \ + -CAfile ca.pem \ + -verify_other demoCA/cacert.pem \ + -issuer demoCA/cacert.pem \ + -cert server.pem \ + -url http://localhost:8888/ \ + -respout ocsp-server-cache.der diff --git a/hs20/server/ca/openssl-root.cnf b/hs20/server/ca/openssl-root.cnf new file mode 100644 index 000000000..5b220fe80 --- /dev/null +++ b/hs20/server/ca/openssl-root.cnf @@ -0,0 +1,125 @@ +# OpenSSL configuration file for Hotspot 2.0 PKI (Root CA) + +HOME = . +RANDFILE = $ENV::HOME/.rnd +oid_section = new_oids + +[ new_oids ] + +#logotypeoid=1.3.6.1.5.5.7.1.12 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = ./rootCA # Where everything is kept +certs = $dir/certs # Where the issued certs are kept +crl_dir = $dir/crl # Where the issued crl are kept +database = $dir/index.txt # database index file. +#unique_subject = no # Set to 'no' to allow creation of + # several certificates with same subject +new_certs_dir = $dir/newcerts # default place for new certs. + +certificate = $dir/cacert.pem # The CA certificate +serial = $dir/serial # The current serial number +crlnumber = $dir/crlnumber # the current crl number + # must be commented out to leave a V1 CRL +crl = $dir/crl.pem # The current CRL +private_key = $dir/private/cakey.pem# The private key +RANDFILE = $dir/private/.rand # private random number file + +x509_extensions = usr_cert # The extentions to add to the cert + +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +default_days = 365 # how long to certify for +default_crl_days= 30 # how long before next CRL +default_md = default # use public key default MD +preserve = no # keep passed DN ordering + +policy = policy_match + +# For the CA policy +[ policy_match ] +countryName = match +stateOrProvinceName = optional +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +#################################################################### +[ req ] +default_bits = 2048 +default_keyfile = privkey.pem +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extentions to add to the self signed cert + +input_password = whatever +output_password = whatever + +string_mask = utf8only + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = US +countryName_min = 2 +countryName_max = 2 + +localityName = Locality Name (eg, city) +localityName_default = Tuusula + +0.organizationName = Organization Name (eg, company) +0.organizationName_default = WFA Hotspot 2.0 + +##organizationalUnitName = Organizational Unit Name (eg, section) +#organizationalUnitName_default = +#@OU@ + +commonName = Common Name (e.g. server FQDN or YOUR name) +#@CN@ +commonName_max = 64 + +emailAddress = Email Address +emailAddress_max = 64 + +[ req_attributes ] + +[ v3_req ] + +# Extensions to add to a certificate request +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +subjectAltName=DNS:example.com,DNS:another.example.com + +[ v3_ca ] + +# Hotspot 2.0 PKI requirements +subjectKeyIdentifier=hash +basicConstraints = critical,CA:true +keyUsage = critical, cRLSign, keyCertSign + +[ crl_ext ] + +# issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + +[ v3_OCSP ] + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = OCSPSigning diff --git a/hs20/server/ca/openssl.cnf b/hs20/server/ca/openssl.cnf new file mode 100644 index 000000000..a939f081e --- /dev/null +++ b/hs20/server/ca/openssl.cnf @@ -0,0 +1,200 @@ +# OpenSSL configuration file for Hotspot 2.0 PKI (Intermediate CA) + +HOME = . +RANDFILE = $ENV::HOME/.rnd +oid_section = new_oids + +[ new_oids ] + +#logotypeoid=1.3.6.1.5.5.7.1.12 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = ./demoCA # Where everything is kept +certs = $dir/certs # Where the issued certs are kept +crl_dir = $dir/crl # Where the issued crl are kept +database = $dir/index.txt # database index file. +#unique_subject = no # Set to 'no' to allow creation of + # several certificates with same subject +new_certs_dir = $dir/newcerts # default place for new certs. + +certificate = $dir/cacert.pem # The CA certificate +serial = $dir/serial # The current serial number +crlnumber = $dir/crlnumber # the current crl number + # must be commented out to leave a V1 CRL +crl = $dir/crl.pem # The current CRL +private_key = $dir/private/cakey.pem# The private key +RANDFILE = $dir/private/.rand # private random number file + +x509_extensions = ext_client # The extentions to add to the cert + +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +# Extension copying option: use with caution. +copy_extensions = copy + +default_days = 365 # how long to certify for +default_crl_days= 30 # how long before next CRL +default_md = default # use public key default MD +preserve = no # keep passed DN ordering + +policy = policy_match + +# For the CA policy +[ policy_match ] +countryName = supplied +stateOrProvinceName = optional +organizationName = supplied +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ policy_osu_server ] +countryName = match +stateOrProvinceName = optional +organizationName = match +organizationalUnitName = supplied +commonName = supplied +emailAddress = optional + +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +#################################################################### +[ req ] +default_bits = 2048 +default_keyfile = privkey.pem +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extentions to add to the self signed cert + +input_password = whatever +output_password = whatever + +string_mask = utf8only + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = FI +countryName_min = 2 +countryName_max = 2 + +localityName = Locality Name (eg, city) +localityName_default = Tuusula + +0.organizationName = Organization Name (eg, company) +0.organizationName_default = w1.fi + +##organizationalUnitName = Organizational Unit Name (eg, section) +#organizationalUnitName_default = +#@OU@ + +commonName = Common Name (e.g. server FQDN or YOUR name) +#@CN@ +commonName_max = 64 + +emailAddress = Email Address +emailAddress_max = 64 + +[ req_attributes ] + +[ v3_ca ] + +# Hotspot 2.0 PKI requirements +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer +basicConstraints = critical, CA:true, pathlen:0 +keyUsage = critical, cRLSign, keyCertSign +authorityInfoAccess = OCSP;URI:http://osu.w1.fi:8888/ +# For SP intermediate CA +#subjectAltName=critical,otherName:1.3.6.1.4.1.40808.1.1.1;UTF8String:engExample OSU +#nameConstraints=permitted;DNS:.w1.fi +#1.3.6.1.5.5.7.1.12=ASN1:SEQUENCE:LogotypeExtn + +[ v3_osu_server ] + +basicConstraints = critical, CA:true, pathlen:0 +keyUsage = critical, keyEncipherment +#@ALTNAME@ + +#logotypeoid=ASN1:SEQUENCE:LogotypeExtn +1.3.6.1.5.5.7.1.12=ASN1:SEQUENCE:LogotypeExtn +[LogotypeExtn] +communityLogos=EXP:0,SEQUENCE:LogotypeInfo +[LogotypeInfo] +# note: implicit tag converted to explicit for CHOICE +direct=EXP:0,SEQUENCE:LogotypeData +[LogotypeData] +image=SEQUENCE:LogotypeImage +[LogotypeImage] +imageDetails=SEQUENCE:LogotypeDetails +imageInfo=SEQUENCE:LogotypeImageInfo +[LogotypeDetails] +mediaType=IA5STRING:image/png +logotypeHash=SEQUENCE:HashAlgAndValues +logotypeURI=SEQUENCE:URI +[HashAlgAndValues] +value1=SEQUENCE:HashAlgAndValueSHA256 +#value2=SEQUENCE:HashAlgAndValueSHA1 +[HashAlgAndValueSHA256] +hashAlg=SEQUENCE:sha256_alg +hashValue=FORMAT:HEX,OCTETSTRING:4532f7ec36424381617c03c6ce87b55a51d6e7177ffafda243cebf280a68954d +[HashAlgAndValueSHA1] +hashAlg=SEQUENCE:sha1_alg +hashValue=FORMAT:HEX,OCTETSTRING:5e1d5085676eede6b02da14d31c523ec20ffba0b +[sha256_alg] +algorithm=OID:sha256 +[sha1_alg] +algorithm=OID:sha1 +[URI] +uri=IA5STRING:http://osu.w1.fi/w1fi_logo.png +[LogotypeImageInfo] +# default value color(1), component optional +#type=IMP:0,INTEGER:1 +fileSize=INTEGER:7549 +xSize=INTEGER:128 +ySize=INTEGER:80 +language=IMP:4,IA5STRING:zxx + +[ crl_ext ] + +# issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + +[ v3_OCSP ] + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = OCSPSigning + +[ ext_client ] + +basicConstraints=CA:FALSE +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer +authorityInfoAccess = OCSP;URI:http://osu.w1.fi:8888/ +#@ALTNAME@ +extendedKeyUsage = clientAuth + +[ ext_server ] + +# Hotspot 2.0 PKI requirements +basicConstraints=critical, CA:FALSE +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer +authorityInfoAccess = OCSP;URI:http://osu.w1.fi:8888/ +#@ALTNAME@ +extendedKeyUsage = critical, serverAuth +keyUsage = critical, keyEncipherment diff --git a/hs20/server/ca/setup.sh b/hs20/server/ca/setup.sh new file mode 100755 index 000000000..f61bf73b6 --- /dev/null +++ b/hs20/server/ca/setup.sh @@ -0,0 +1,125 @@ +#!/bin/sh + +if [ -z "$OPENSSL" ]; then + OPENSSL=openssl +fi +export OPENSSL_CONF=$PWD/openssl.cnf +PASS=whatever + +fail() +{ + echo "$*" + exit 1 +} + +echo +echo "---[ Root CA ]----------------------------------------------------------" +echo + +cat openssl-root.cnf | sed "s/#@CN@/commonName_default = Hotspot 2.0 Trust Root CA - 99/" > openssl.cnf.tmp +mkdir -p rootCA/certs rootCA/crl rootCA/newcerts rootCA/private +touch rootCA/index.txt +if [ -e rootCA/private/cakey.pem ]; then + echo " * Use existing Root CA" +else + echo " * Generate Root CA private key" + $OPENSSL req -config openssl.cnf.tmp -batch -new -newkey rsa:4096 -keyout rootCA/private/cakey.pem -out rootCA/careq.pem || fail "Failed to generate Root CA private key" + echo " * Sign Root CA certificate" + $OPENSSL ca -config openssl.cnf.tmp -md sha256 -create_serial -out rootCA/cacert.pem -days 10957 -batch -keyfile rootCA/private/cakey.pem -passin pass:$PASS -selfsign -extensions v3_ca -outdir rootCA/newcerts -infiles rootCA/careq.pem || fail "Failed to sign Root CA certificate" +fi +if [ ! -e rootCA/crlnumber ]; then + echo 00 > rootCA/crlnumber +fi + +echo +echo "---[ Intermediate CA ]--------------------------------------------------" +echo + +cat openssl.cnf | sed "s/#@CN@/commonName_default = w1.fi Hotspot 2.0 Intermediate CA/" > openssl.cnf.tmp +mkdir -p demoCA/certs demoCA/crl demoCA/newcerts demoCA/private +touch demoCA/index.txt +if [ -e demoCA/private/cakey.pem ]; then + echo " * Use existing Intermediate CA" +else + echo " * Generate Intermediate CA private key" + $OPENSSL req -config openssl.cnf.tmp -batch -new -newkey rsa:2048 -keyout demoCA/private/cakey.pem -out demoCA/careq.pem || fail "Failed to generate Intermediate CA private key" + echo " * Sign Intermediate CA certificate" + $OPENSSL ca -config openssl.cnf.tmp -md sha256 -create_serial -out demoCA/cacert.pem -days 3652 -batch -keyfile rootCA/private/cakey.pem -cert rootCA/cacert.pem -passin pass:$PASS -extensions v3_ca -infiles demoCA/careq.pem || fail "Failed to sign Intermediate CA certificate" + # horrible from security view point, but for testing purposes since OCSP responder does not seem to support -passin + openssl rsa -in demoCA/private/cakey.pem -out demoCA/private/cakey-plain.pem -passin pass:$PASS +fi +if [ ! -e demoCA/crlnumber ]; then + echo 00 > demoCA/crlnumber +fi + +echo +echo "OCSP responder" +echo + +cat openssl.cnf | sed "s/#@CN@/commonName_default = ocsp.w1.fi/" > openssl.cnf.tmp +$OPENSSL req -config $PWD/openssl.cnf.tmp -batch -new -newkey rsa:2048 -nodes -out ocsp.csr -keyout ocsp.key -extensions v3_OCSP +$OPENSSL ca -config $PWD/openssl.cnf.tmp -batch -md sha256 -keyfile demoCA/private/cakey.pem -passin pass:$PASS -in ocsp.csr -out ocsp.pem -days 730 -extensions v3_OCSP + +echo +echo "---[ Server - to be revoked ] ------------------------------------------" +echo + +cat openssl.cnf | sed "s/#@CN@/commonName_default = osu-revoked.w1.fi/" > openssl.cnf.tmp +$OPENSSL req -config $PWD/openssl.cnf.tmp -batch -new -newkey rsa:2048 -nodes -out server-revoked.csr -keyout server-revoked.key +$OPENSSL ca -config $PWD/openssl.cnf.tmp -batch -md sha256 -in server-revoked.csr -out server-revoked.pem -key $PASS -days 730 -extensions ext_server +$OPENSSL ca -revoke server-revoked.pem -key $PASS + +echo +echo "---[ Server - with client ext key use ] ---------------------------------" +echo + +cat openssl.cnf | sed "s/#@CN@/commonName_default = osu-client.w1.fi/" > openssl.cnf.tmp +$OPENSSL req -config $PWD/openssl.cnf.tmp -batch -new -newkey rsa:2048 -nodes -out server-client.csr -keyout server-client.key +$OPENSSL ca -config $PWD/openssl.cnf.tmp -batch -md sha256 -in server-client.csr -out server-client.pem -key $PASS -days 730 -extensions ext_client + +echo +echo "---[ User ]-------------------------------------------------------------" +echo + +cat openssl.cnf | sed "s/#@CN@/commonName_default = User/" > openssl.cnf.tmp +$OPENSSL req -config $PWD/openssl.cnf.tmp -batch -new -newkey rsa:2048 -nodes -out user.csr -keyout user.key +$OPENSSL ca -config $PWD/openssl.cnf.tmp -batch -md sha256 -in user.csr -out user.pem -key $PASS -days 730 -extensions ext_client + +echo +echo "---[ Server ]-----------------------------------------------------------" +echo + +ALT="DNS:osu.w1.fi" +ALT="$ALT,otherName:1.3.6.1.4.1.40808.1.1.1;UTF8String:engw1.fi TESTING USE" +ALT="$ALT,otherName:1.3.6.1.4.1.40808.1.1.1;UTF8String:finw1.fi TESTIKÄYTTÖ" + +cat openssl.cnf | + sed "s/#@CN@/commonName_default = osu.w1.fi/" | + sed "s/^##organizationalUnitName/organizationalUnitName/" | + sed "s/#@OU@/organizationalUnitName_default = Hotspot 2.0 Online Sign Up Server/" | + sed "s/#@ALTNAME@/subjectAltName=critical,$ALT/" \ + > openssl.cnf.tmp +echo $OPENSSL req -config $PWD/openssl.cnf.tmp -batch -sha256 -new -newkey rsa:2048 -nodes -out server.csr -keyout server.key -reqexts v3_osu_server +$OPENSSL req -config $PWD/openssl.cnf.tmp -batch -sha256 -new -newkey rsa:2048 -nodes -out server.csr -keyout server.key -reqexts v3_osu_server || fail "Failed to generate server request" +$OPENSSL ca -config $PWD/openssl.cnf.tmp -batch -md sha256 -in server.csr -out server.pem -key $PASS -days 730 -extensions ext_server -policy policy_osu_server || fail "Failed to sign server certificate" + +#dump logotype details for debugging +$OPENSSL x509 -in server.pem -out server.der -outform DER +openssl asn1parse -in server.der -inform DER | grep HEX | tail -1 | sed 's/.*://' | xxd -r -p > logo.der +openssl asn1parse -in logo.der -inform DER > logo.asn1 + + +echo +echo "---[ CRL ]---------------------------------------------------------------" +echo + +$OPENSSL ca -config $PWD/openssl.cnf -gencrl -md sha256 -out demoCA/crl/crl.pem -passin pass:$PASS + +echo +echo "---[ Verify ]------------------------------------------------------------" +echo + +$OPENSSL verify -CAfile rootCA/cacert.pem demoCA/cacert.pem +$OPENSSL verify -CAfile rootCA/cacert.pem -untrusted demoCA/cacert.pem *.pem + +cat rootCA/cacert.pem demoCA/cacert.pem > ca.pem diff --git a/hs20/server/ca/w1fi_logo.png b/hs20/server/ca/w1fi_logo.png new file mode 100644 index 000000000..ac7c259ff Binary files /dev/null and b/hs20/server/ca/w1fi_logo.png differ