723 lines
21 KiB
Diff
723 lines
21 KiB
Diff
|
From 6d50f87a06ff70d2075863f4c145235c081263d6 Mon Sep 17 00:00:00 2001
|
||
|
From: Matthew Garrett <mjg59@srcf.ucam.org>
|
||
|
Date: Sat, 24 Nov 2012 00:07:11 -0500
|
||
|
Subject: [PATCH 1/2] Sign MokManager with a locally-generated key
|
||
|
|
||
|
shim needs to verify that MokManager hasn't been modified, but we want to
|
||
|
be able to support configurations where shim is shipped without a vendor
|
||
|
certificate. This patch adds support for generating a certificate at build
|
||
|
time, incorporating the public half into shim and signing MokManager with
|
||
|
the private half. It uses pesign and nss, but still requires openssl for
|
||
|
key generation. Anyone using sbsign will need to figure this out for
|
||
|
themselves.
|
||
|
---
|
||
|
Makefile | 28 ++-
|
||
|
make-certs | 554 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
shim.c | 24 ++-
|
||
|
3 files changed, 597 insertions(+), 9 deletions(-)
|
||
|
create mode 100755 make-certs
|
||
|
|
||
|
diff --git a/Makefile b/Makefile
|
||
|
index b266018..412eba5 100644
|
||
|
--- a/Makefile
|
||
|
+++ b/Makefile
|
||
|
@@ -28,15 +28,33 @@ LDFLAGS = -nostdlib -znocombreloc -T $(EFI_LDS) -shared -Bsymbolic -L$(EFI_PATH
|
||
|
|
||
|
VERSION = 0.2
|
||
|
|
||
|
-TARGET = shim.efi MokManager.efi
|
||
|
+TARGET = shim.efi MokManager.efi.signed
|
||
|
OBJS = shim.o netboot.o cert.o dbx.o
|
||
|
+KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key
|
||
|
SOURCES = shim.c shim.h netboot.c signature.h PeImage.h
|
||
|
MOK_OBJS = MokManager.o
|
||
|
MOK_SOURCES = MokManager.c shim.h
|
||
|
|
||
|
all: $(TARGET)
|
||
|
|
||
|
-shim.o: $(SOURCES)
|
||
|
+shim.crt:
|
||
|
+ ./make-certs shim shim@xn--u4h.net all codesign 1.3.6.1.4.1.311.10.3.1 </dev/null
|
||
|
+
|
||
|
+shim.cer: shim.crt
|
||
|
+ openssl x509 -outform der -in $< -out $@
|
||
|
+
|
||
|
+shim_cert.h: shim.cer
|
||
|
+ echo "static UINT8 shim_cert[] = {" > $@
|
||
|
+ hexdump -v -e '1/1 "0x%02x, "' $< >> $@
|
||
|
+ echo "};" >> $@
|
||
|
+
|
||
|
+certdb/secmod.db: shim.crt
|
||
|
+ -mkdir certdb
|
||
|
+ certutil -A -n 'my CA' -d certdb/ -t CT,CT,CT -i ca.crt
|
||
|
+ pk12util -d certdb/ -i shim.p12 -W "" -K ""
|
||
|
+ certutil -d certdb/ -A -i shim.crt -n shim -t u
|
||
|
+
|
||
|
+shim.o: $(SOURCES) shim_cert.h
|
||
|
|
||
|
cert.o : cert.S
|
||
|
$(CC) $(CFLAGS) -c -o $@ $<
|
||
|
@@ -70,10 +88,14 @@ Cryptlib/OpenSSL/libopenssl.a:
|
||
|
-j .debug_line -j .debug_str -j .debug_ranges \
|
||
|
--target=efi-app-$(ARCH) $^ $@.debug
|
||
|
|
||
|
+%.efi.signed: %.efi certdb/secmod.db
|
||
|
+ pesign -n certdb -i $< -c "shim" -s -o $@ -f
|
||
|
+
|
||
|
clean:
|
||
|
$(MAKE) -C Cryptlib clean
|
||
|
$(MAKE) -C Cryptlib/OpenSSL clean
|
||
|
- rm -f $(TARGET) $(OBJS)
|
||
|
+ rm -rf $(TARGET) $(OBJS) $(MOK_OBJS) $(KEYS) certdb
|
||
|
+ rm -f *.debug *.so
|
||
|
|
||
|
GITTAG = $(VERSION)
|
||
|
|
||
|
diff --git a/make-certs b/make-certs
|
||
|
new file mode 100755
|
||
|
index 0000000..3e9293b
|
||
|
--- /dev/null
|
||
|
+++ b/make-certs
|
||
|
@@ -0,0 +1,554 @@
|
||
|
+#!/bin/bash -e
|
||
|
+#
|
||
|
+# Generate a root CA cert for signing, and then a subject cert.
|
||
|
+# Usage: make-certs.sh hostname [user[@domain]] [more ...]
|
||
|
+# For testing only, probably still has some bugs in it.
|
||
|
+#
|
||
|
+
|
||
|
+DOMAIN=xn--u4h.net
|
||
|
+DAYS=365
|
||
|
+KEYTYPE=RSA
|
||
|
+KEYSIZE=2048
|
||
|
+DIGEST=SHA256
|
||
|
+CRLHOURS=24
|
||
|
+CRLDAYS=
|
||
|
+
|
||
|
+# Cleanup temporary files at exit.
|
||
|
+touch openssl.cnf
|
||
|
+newcertdir=`mktemp -d`
|
||
|
+cleanup() {
|
||
|
+ test -f openssl.cnf && rm -f openssl.cnf
|
||
|
+ test -f ca.txt && rm -f ca.txt
|
||
|
+ test -f ocsp.txt && rm -f ocsp.txt
|
||
|
+ test -n "$newcertdir" && rm -fr "$newcertdir"
|
||
|
+}
|
||
|
+trap cleanup EXIT
|
||
|
+
|
||
|
+# The first argument is either a common name value or a flag indicating that
|
||
|
+# we're doing something other than issuing a cert.
|
||
|
+commonname="$1"
|
||
|
+refresh_crl=false
|
||
|
+revoke_cert=false
|
||
|
+ocsp_serve=false
|
||
|
+if test "x$commonname" = "x-refresh-crl" ; then
|
||
|
+ refresh_crl=true
|
||
|
+ commonname="$1"
|
||
|
+fi
|
||
|
+if test "x$commonname" = "x-refresh_crl" ; then
|
||
|
+ refresh_crl=true
|
||
|
+ commonname="$1"
|
||
|
+fi
|
||
|
+if test "x$commonname" = "x-revoke" ; then
|
||
|
+ revoke_cert=true
|
||
|
+ shift
|
||
|
+ commonname="$1"
|
||
|
+fi
|
||
|
+if test "x$commonname" = "x-ocsp" ; then
|
||
|
+ ocsp_serve=true
|
||
|
+ commonname="$1"
|
||
|
+fi
|
||
|
+if test "x$commonname" = x ; then
|
||
|
+ echo Usage: `basename $0` 'commonname' user'[@domain]' '[more [...]]'
|
||
|
+ echo Usage: `basename $0` -revoke 'commonname'
|
||
|
+ echo Usage: `basename $0` -ocsp
|
||
|
+ echo Usage: `basename $0` -refresh-crl
|
||
|
+ echo More:
|
||
|
+ echo -e \\tKey usage: "[sign|signing|encrypt|encryption|all]"
|
||
|
+ echo -e \\tAuthority Access Info OCSP responder: "ocsp:URI"
|
||
|
+ echo -e \\tCRL distribution point: "crl:URI"
|
||
|
+ echo -e \\tSubject Alternative Name:
|
||
|
+ echo -e \\t\\tHostname: "*"
|
||
|
+ echo -e \\t\\tIP address: w.x.y.z
|
||
|
+ echo -e \\t\\tEmail address: "*@*.com/edu/net/org/local"
|
||
|
+ echo -e \\t\\tKerberos principal name: "*@*.COM/EDU/NET/ORG/LOCAL"
|
||
|
+ echo -e \\tExtended key usage:
|
||
|
+ echo -e \\t\\t1....
|
||
|
+ echo -e \\t\\t2....
|
||
|
+ echo -e \\t\\tid-kp-server-auth \| tls-server
|
||
|
+ echo -e \\t\\tid-kp-client-auth \| tls-client
|
||
|
+ echo -e \\t\\tid-kp-email-protection \| email
|
||
|
+ echo -e \\t\\tid-ms-kp-sc-logon \| id-ms-sc-logon
|
||
|
+ echo -e \\t\\tid-pkinit-kp-client-auth \| id-pkinit-client
|
||
|
+ echo -e \\t\\tid-pkinit-kp-kdc \| id-pkinit-kdc
|
||
|
+ echo -e \\t\\tca \| CA
|
||
|
+ exit 1
|
||
|
+fi
|
||
|
+
|
||
|
+# Choose a user name part for email attributes.
|
||
|
+GIVENUSER=$2
|
||
|
+test x"$GIVENUSER" = x && GIVENUSER=$USER
|
||
|
+echo "$GIVENUSER" | grep -q @ || GIVENUSER="$GIVENUSER"@$DOMAIN
|
||
|
+DOMAIN=`echo "$GIVENUSER" | cut -f2- -d@`
|
||
|
+
|
||
|
+shift || true
|
||
|
+shift || true
|
||
|
+
|
||
|
+# Done already?
|
||
|
+done=:
|
||
|
+
|
||
|
+keygen() {
|
||
|
+ case "$KEYTYPE" in
|
||
|
+ DSA)
|
||
|
+ openssl dsaparam -out "$1".param $KEYSIZE
|
||
|
+ openssl gendsa "$1".param
|
||
|
+ ;;
|
||
|
+ RSA|*)
|
||
|
+ #openssl genrsa $KEYSIZE -passout pass:qweqwe
|
||
|
+ openssl genrsa $KEYSIZE
|
||
|
+ #openssl genrsa $KEYSIZE -nodes
|
||
|
+ ;;
|
||
|
+ esac
|
||
|
+}
|
||
|
+
|
||
|
+# Set some defaults.
|
||
|
+CA=FALSE
|
||
|
+if test -s ca.crldp.uri.txt ; then
|
||
|
+ crlval="`cat ca.crldp.uri.txt`"
|
||
|
+ crl="URI:$crlval"
|
||
|
+fi
|
||
|
+if test -s ca.ocsp.uri.txt ; then
|
||
|
+ aiaval="`cat ca.ocsp.uri.txt`"
|
||
|
+ aia="OCSP;URI:$aiaval"
|
||
|
+fi
|
||
|
+if test -s ca.domain.txt ; then
|
||
|
+ domval="`cat ca.domain.txt`"
|
||
|
+ if test -n "$domval" ; then
|
||
|
+ DOMAIN="$domval"
|
||
|
+ fi
|
||
|
+fi
|
||
|
+
|
||
|
+# Parse the arguments which indicate what sort of information we want.
|
||
|
+while test $# -gt 0 ; do
|
||
|
+ type=
|
||
|
+ value="$1"
|
||
|
+ case "$value" in
|
||
|
+ RSA|rsa)
|
||
|
+ KEYTYPE=RSA
|
||
|
+ ;;
|
||
|
+ DSA|dsa)
|
||
|
+ KEYTYPE=DSA
|
||
|
+ ;;
|
||
|
+ OCSP:*|ocsp:*)
|
||
|
+ aiaval=`echo "$value" | cut -f2- -d:`
|
||
|
+ aia="OCSP;URI:$aiaval"
|
||
|
+ ;;
|
||
|
+ CRL:*|crl:*)
|
||
|
+ crlval=`echo "$value" | cut -f2- -d:`
|
||
|
+ crl="URI:$crlval"
|
||
|
+ ;;
|
||
|
+ signing|sign)
|
||
|
+ keyusage="${keyusage:+${keyusage},}nonRepudiation,digitalSignature"
|
||
|
+ ;;
|
||
|
+ encryption|encrypt)
|
||
|
+ keyusage="${keyusage:+${keyusage},}keyEncipherment,dataEncipherment"
|
||
|
+ ;;
|
||
|
+ all)
|
||
|
+ keyusage="digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign,encipherOnly,decipherOnly"
|
||
|
+ ;;
|
||
|
+ ca|CA)
|
||
|
+ CA=TRUE
|
||
|
+ keyusage="${keyusage:+${keyusage},}nonRepudiation,digitalSignature,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign"
|
||
|
+ ;;
|
||
|
+ 1.*|2.*|id-*|tls-*|email|mail|codesign)
|
||
|
+ ekuval=`echo "$value" | tr '[A-Z]' '[a-z]' | sed 's,\-,,g'`
|
||
|
+ case "$ekuval" in
|
||
|
+ idkpserverauth|tlsserver) ekuval=1.3.6.1.5.5.7.3.1;;
|
||
|
+ idkpclientauth|tlsclient) ekuval=1.3.6.1.5.5.7.3.2;;
|
||
|
+ idkpemailprotection|email|mail) ekuval=1.3.6.1.5.5.7.3.4;;
|
||
|
+ idkpcodesign|codesign) ekuval=1.3.6.1.5.5.7.3.3;;
|
||
|
+ idmskpsclogon|idmssclogon) ekuval=1.3.6.1.4.1.311.20.2.2;;
|
||
|
+ idpkinitkpclientauth|idpkinitclient) ekuval=1.3.6.1.5.2.3.4;;
|
||
|
+ idpkinitkpkdc|idpkinitkdc) ekuval=1.3.6.1.5.2.3.5;;
|
||
|
+ esac
|
||
|
+ if test -z "$eku" ; then
|
||
|
+ eku="$ekuval"
|
||
|
+ else
|
||
|
+ eku="$eku,$ekuval"
|
||
|
+ fi
|
||
|
+ ;;
|
||
|
+ *@*.COM|*@*.EDU|*@*.NET|*@*.ORG|*@*.LOCAL)
|
||
|
+ luser=`echo "$value" | tr '[A-Z]' '[a-z]'`
|
||
|
+ if test "$luser" = "$value" ; then
|
||
|
+ luser=
|
||
|
+ fi
|
||
|
+ type="otherName:1.3.6.1.5.2.2;SEQUENCE:$value,${luser:+otherName:1.3.6.1.4.1.311.20.2.3;UTF8:${luser},}otherName:1.3.6.1.4.1.311.20.2.3;UTF8"
|
||
|
+ unset luser
|
||
|
+ principals="$principals $value"
|
||
|
+ ;;
|
||
|
+ *@*.com|*@*.edu|*@*.net|*@*.org|*@*.local) type=email;;
|
||
|
+ [0-9]*.[0-9]*.[0-9]*.[0-9]*) type=IP;;
|
||
|
+ *) type=DNS;;
|
||
|
+ esac
|
||
|
+ if test -n "$type" ; then
|
||
|
+ newvalue="${type}:$value"
|
||
|
+ if test -z "$altnames" ; then
|
||
|
+ altnames="${newvalue}"
|
||
|
+ else
|
||
|
+ altnames="${altnames},${newvalue}"
|
||
|
+ fi
|
||
|
+ fi
|
||
|
+ shift
|
||
|
+done
|
||
|
+
|
||
|
+# Build the configuration file, including bits on how to construct the CA
|
||
|
+# certificate, an OCSP responder certificate, and the issued certificate.
|
||
|
+cat > openssl.cnf <<- EOF
|
||
|
+[ca]
|
||
|
+default_ca = issuer
|
||
|
+
|
||
|
+[issuer]
|
||
|
+private_key = `pwd`/ca.key
|
||
|
+certificate = `pwd`/ca.crt
|
||
|
+database = `pwd`/ca.db
|
||
|
+serial = `pwd`/ca.srl
|
||
|
+default_md = $DIGEST
|
||
|
+new_certs_dir = $newcertdir
|
||
|
+policy = no_policy
|
||
|
+
|
||
|
+[no_policy]
|
||
|
+
|
||
|
+[req_oids]
|
||
|
+domainComponent = 0.9.2342.19200300.100.1.25
|
||
|
+
|
||
|
+[req_ca]
|
||
|
+prompt = no
|
||
|
+oid_section = req_oids
|
||
|
+distinguished_name = req_ca_name
|
||
|
+default_md = $DIGEST
|
||
|
+subjectKeyIdentifier=hash
|
||
|
+
|
||
|
+[req_ca_name]
|
||
|
+C=US
|
||
|
+#stateOrProvinceName=SomeState
|
||
|
+localityName=SomeCity
|
||
|
+O=SomeOrg
|
||
|
+EOF
|
||
|
+#echo $DOMAIN | awk 'BEGIN {FS="."}{for(i=NF;i>0;i--){print NF-i ".domainComponent="$i;}}' >> openssl.cnf
|
||
|
+cat >> openssl.cnf <<- EOF
|
||
|
+#commonName = Test Certifying CA
|
||
|
+
|
||
|
+[v3_ca]
|
||
|
+subjectKeyIdentifier=hash
|
||
|
+authorityKeyIdentifier=keyid:always
|
||
|
+#authorityKeyIdentifier=keyid:always,issuer:always
|
||
|
+keyUsage=nonRepudiation,digitalSignature,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign
|
||
|
+basicConstraints=critical,CA:TRUE
|
||
|
+nsComment="Testing CA Certificate"
|
||
|
+EOF
|
||
|
+if test -n "$aia" ; then
|
||
|
+ echo "authorityInfoAccess = ${aia}" >> openssl.cnf
|
||
|
+ echo -n "$aiaval" > ca.ocsp.uri.txt
|
||
|
+fi
|
||
|
+if test -n "$crl" ; then
|
||
|
+ echo "crlDistributionPoints = ${crl}" >> openssl.cnf
|
||
|
+ echo -n "$crlval" > ca.crldp.uri.txt
|
||
|
+fi
|
||
|
+echo "$DOMAIN" > ca.domain.txt
|
||
|
+cat >> openssl.cnf <<- EOF
|
||
|
+
|
||
|
+[req_ocsp]
|
||
|
+prompt = no
|
||
|
+oid_section = req_oids
|
||
|
+distinguished_name = req_ocsp_name
|
||
|
+default_md = $DIGEST
|
||
|
+
|
||
|
+[req_ocsp_name]
|
||
|
+C=US
|
||
|
+#stateOrProvinceName=SomeState
|
||
|
+localityName=SomeOrg
|
||
|
+O=SomeOrg
|
||
|
+EOF
|
||
|
+#echo $DOMAIN | awk 'BEGIN {FS="."}{for(i=NF;i>0;i--){print NF-i ".domainComponent="$i;}}' >> openssl.cnf
|
||
|
+cat >> openssl.cnf <<- EOF
|
||
|
+#commonName = OCSP Signer for Test Certifying CA
|
||
|
+
|
||
|
+[v3_ocsp]
|
||
|
+subjectKeyIdentifier=hash
|
||
|
+#authorityKeyIdentifier=keyid:always,issuer:always
|
||
|
+authorityKeyIdentifier=keyid:always
|
||
|
+keyUsage=digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign
|
||
|
+extendedKeyUsage=1.3.6.1.5.5.7.3.9
|
||
|
+#basicConstraints=CA:FALSE
|
||
|
+basicConstraints=CA:TRUE
|
||
|
+nsComment="Testing OCSP Certificate"
|
||
|
+1.3.6.1.5.5.7.48.1.5=ASN1:NULL
|
||
|
+EOF
|
||
|
+if test -n "$aia" ; then
|
||
|
+ echo "authorityInfoAccess = ${aia}" >> openssl.cnf
|
||
|
+fi
|
||
|
+if test -n "$crl" ; then
|
||
|
+ echo "crlDistributionPoints = ${crl}" >> openssl.cnf
|
||
|
+fi
|
||
|
+cat >> openssl.cnf <<- EOF
|
||
|
+
|
||
|
+[req_issued]
|
||
|
+prompt = no
|
||
|
+oid_section = req_oids
|
||
|
+distinguished_name = req_issued_name
|
||
|
+default_md = $DIGEST
|
||
|
+
|
||
|
+[req_issued_name]
|
||
|
+C=US
|
||
|
+#stateOrProvinceName=SomeState
|
||
|
+localityName=SomeCity
|
||
|
+O=SomeOrg
|
||
|
+EOF
|
||
|
+#echo $DOMAIN | awk 'BEGIN {FS="."}{for(i=NF;i>0;i--){print NF-i ".domainComponent="$i;}}' >> openssl.cnf
|
||
|
+#mail = $GIVENUSER
|
||
|
+cat >> openssl.cnf <<- EOF
|
||
|
+commonName = $commonname
|
||
|
+
|
||
|
+[v3_issued]
|
||
|
+#certificatePolicies=2.5.29.32.0${eku:+,${eku}}
|
||
|
+subjectKeyIdentifier=hash
|
||
|
+authorityKeyIdentifier=keyid:always
|
||
|
+#authorityKeyIdentifier=keyid:always,issuer:always
|
||
|
+EOF
|
||
|
+if test -n "$aia" ; then
|
||
|
+ echo "authorityInfoAccess = ${aia}" >> openssl.cnf
|
||
|
+fi
|
||
|
+if test -n "$crl" ; then
|
||
|
+ echo "crlDistributionPoints = ${crl}" >> openssl.cnf
|
||
|
+fi
|
||
|
+if test -n "$keyusage" ; then
|
||
|
+ echo "keyUsage = critical,${keyusage}" >> openssl.cnf
|
||
|
+fi
|
||
|
+if test -n "$altnames" ; then
|
||
|
+ echo "subjectAltName = ${altnames}" >> openssl.cnf
|
||
|
+fi
|
||
|
+if test -n "$eku" ; then
|
||
|
+ echo "extendedKeyUsage = ${eku}" >> openssl.cnf
|
||
|
+ :
|
||
|
+fi
|
||
|
+if test "x$CA" = xTRUE ; then
|
||
|
+ echo "basicConstraints=critical,CA:TRUE" >> openssl.cnf
|
||
|
+ echo 'nsComment="Testing CA Certificate for '"$commonname"'"' >> openssl.cnf
|
||
|
+else
|
||
|
+ echo "basicConstraints=CA:FALSE" >> openssl.cnf
|
||
|
+ echo 'nsComment="Testing Certificate for '"$commonname"'"' >> openssl.cnf
|
||
|
+fi
|
||
|
+for value in $principals; do
|
||
|
+ user=`echo "$value" | cut -f1 -d@`
|
||
|
+ realm=`echo "$value" | cut -f2- -d@`
|
||
|
+ echo "" >> openssl.cnf
|
||
|
+ echo "[$value]" >> openssl.cnf
|
||
|
+ echo "realm=EXPLICIT:0,GeneralString:$realm" >> openssl.cnf
|
||
|
+ echo "kerberosname=EXPLICIT:1,SEQUENCE:krb5$user" >> openssl.cnf
|
||
|
+
|
||
|
+ echo "" >> openssl.cnf
|
||
|
+ echo "[krb5$user]" >> openssl.cnf
|
||
|
+ echo "nametype=EXPLICIT:0,INTEGER:1" >> openssl.cnf
|
||
|
+ echo "namelist=EXPLICIT:1,SEQUENCE:krb5basic$user" >> openssl.cnf
|
||
|
+
|
||
|
+ echo "[krb5basic$user]" >> openssl.cnf
|
||
|
+ count=0
|
||
|
+ for part in `echo "$user" | sed 's,/, ,g'` ; do
|
||
|
+ echo "$count.part=GeneralString:$part" >> openssl.cnf
|
||
|
+ count=`expr "$count" + 1`
|
||
|
+ done
|
||
|
+done
|
||
|
+
|
||
|
+# Create the data files for a new CA.
|
||
|
+if ! test -s ca.srl ; then
|
||
|
+ (dd if=/dev/urandom bs=8 count=1 2> /dev/null) | od -t x1c | head -n 1 | awk '{$1="00";OFS="";print}' > ca.srl
|
||
|
+else
|
||
|
+ echo "You already have a ca.srl file; not replacing."
|
||
|
+fi
|
||
|
+if ! test -s ca.db ; then
|
||
|
+ touch ca.db
|
||
|
+else
|
||
|
+ echo "You already have a ca.db file; not replacing."
|
||
|
+fi
|
||
|
+if ! test -s ca.db.attr ; then
|
||
|
+ touch ca.db.attr
|
||
|
+else
|
||
|
+ echo "You already have a ca.db.attr file; not replacing."
|
||
|
+fi
|
||
|
+
|
||
|
+# If we need a CA key, generate one.
|
||
|
+if ! test -s ca.key ; then
|
||
|
+ umask=`umask -p`
|
||
|
+ umask 077
|
||
|
+ keygen ca > ca.key 2> /dev/null
|
||
|
+ $umask
|
||
|
+else
|
||
|
+ echo "You already have a ca.key file; not replacing."
|
||
|
+ done=echo
|
||
|
+fi
|
||
|
+
|
||
|
+# If we need a CA certificate, generate one.
|
||
|
+if ! test -s ca.crt ; then
|
||
|
+ sed -i -e 's,^\[req_ca\]$,\[req\],g' `pwd`/openssl.cnf
|
||
|
+ openssl req -config `pwd`/openssl.cnf -new -key ca.key > ca.csr 2> /dev/null -passin pass:shim
|
||
|
+ sed -i -e 's,^\[req\]$,\[req_ca\],g' `pwd`/openssl.cnf
|
||
|
+ openssl x509 -extfile `pwd`/openssl.cnf -CAserial ca.srl -signkey ca.key -extensions v3_ca -req -in ca.csr -days $DAYS -out ca.crt ; : 2> /dev/null
|
||
|
+ openssl x509 -noout -text -in ca.crt > ca.txt
|
||
|
+ cat ca.crt >> ca.txt
|
||
|
+ cat ca.txt > ca.crt
|
||
|
+ rm ca.txt
|
||
|
+ cat ca.crt > ca.chain.crt
|
||
|
+else
|
||
|
+ echo "You already have a ca.crt file; not replacing."
|
||
|
+ done=echo
|
||
|
+fi
|
||
|
+
|
||
|
+# If we need an OCSP key, generate one.
|
||
|
+if ! test -s ocsp.key ; then
|
||
|
+ umask=`umask -p`
|
||
|
+ umask 077
|
||
|
+ keygen ocsp > ocsp.key 2> /dev/null
|
||
|
+ $umask
|
||
|
+else
|
||
|
+ echo "You already have an ocsp.key file; not replacing."
|
||
|
+ done=echo
|
||
|
+fi
|
||
|
+
|
||
|
+# Generate the OCSP signing cert. Set the X.509v3 basic constraints and EKU.
|
||
|
+if ! test -s ocsp.crt ; then
|
||
|
+ sed -i -e 's,^\[req_ocsp\]$,\[req\],g' `pwd`/openssl.cnf
|
||
|
+ openssl req -config `pwd`/openssl.cnf -new -key ocsp.key > ocsp.csr 2> /dev/null
|
||
|
+ sed -i -e 's,^\[req\]$,\[req_ocsp\],g' `pwd`/openssl.cnf
|
||
|
+ openssl ca -batch -config `pwd`/openssl.cnf -extensions v3_ocsp -preserveDN -in ocsp.csr -days $DAYS -out ocsp.crt 2> /dev/null
|
||
|
+ openssl x509 -noout -text -in ocsp.crt > ocsp.txt
|
||
|
+ cat ocsp.crt >> ocsp.txt
|
||
|
+ cat ocsp.txt > ocsp.crt
|
||
|
+ rm ocsp.txt
|
||
|
+else
|
||
|
+ echo "You already have an ocsp.crt file; not replacing."
|
||
|
+ done=echo
|
||
|
+fi
|
||
|
+
|
||
|
+# If we were told to revoke the certificate with the specified common name,
|
||
|
+# do so.
|
||
|
+if $revoke_cert ; then
|
||
|
+ openssl ca -config `pwd`/openssl.cnf -revoke "$commonname".crt
|
||
|
+fi
|
||
|
+
|
||
|
+# Always refresh the CRL.
|
||
|
+openssl ca -config `pwd`/openssl.cnf -gencrl ${CRLHOURS:+-crlhours ${CRLHOURS}} ${CRLDAYS:+-crldays ${CRLDAYS}} -out ca.crl.pem
|
||
|
+openssl crl -in ca.crl.pem -outform der -out ca.crl
|
||
|
+openssl crl -in ca.crl -inform der -noout -text > ca.crl.pem
|
||
|
+openssl crl -in ca.crl -inform der >> ca.crl.pem
|
||
|
+
|
||
|
+# If we were told to start up the mini OCSP server, do so.
|
||
|
+if $ocsp_serve ; then
|
||
|
+ openssl ocsp -text -index `pwd`/ca.db -CA `pwd`/ca.crt -rsigner `pwd`/ocsp.crt -rkey `pwd`/ocsp.key -rother `pwd`/ocsp.crt -port "`cut -f3 -d/ ca.ocsp.uri.txt | sed -r 's,(^[^:]*),0.0.0.0,g'`"
|
||
|
+ exit 0
|
||
|
+fi
|
||
|
+
|
||
|
+# If we're just here to do a revocation or refresh the CRL, we're done.
|
||
|
+if $revoke_cert || $refresh_crl ; then
|
||
|
+ exit 0
|
||
|
+fi
|
||
|
+
|
||
|
+# Create a new serial number and whatnot if this is a new sub-CA.
|
||
|
+if test "x$CA" = xTRUE ; then
|
||
|
+ if ! test -d "$commonname" ; then
|
||
|
+ mkdir "$commonname"
|
||
|
+ fi
|
||
|
+ if ! test -s "$commonname/ca.srl" ; then
|
||
|
+ (dd if=/dev/urandom bs=8 count=1 2> /dev/null) | od -t x1c | head -n 1 | awk '{$1="00";OFS="";print}' > "$commonname/ca.srl"
|
||
|
+ else
|
||
|
+ echo "You already have a $commonname/ca.srl file; not replacing."
|
||
|
+ fi
|
||
|
+ if test -n "$aia" ; then
|
||
|
+ echo -n "$aiaval" > "$commonname/ca.ocsp.uri.txt"
|
||
|
+ fi
|
||
|
+ if test -n "$crl" ; then
|
||
|
+ echo -n "$crlval" > "$commonname/ca.crldp.uri.txt"
|
||
|
+ fi
|
||
|
+ echo "$DOMAIN" > "$commonname/ca.domain.txt"
|
||
|
+ touch "$commonname/ca.db" "$commonname/ca.db.attr"
|
||
|
+ cert="$commonname/ca.crt"
|
||
|
+ csr="$commonname/ca.csr"
|
||
|
+ key="$commonname/ca.key"
|
||
|
+ pem="$commonname/ca.pem"
|
||
|
+ pfx="$commonname/ca.p12"
|
||
|
+ ln -s ../`basename $0` "$commonname"/
|
||
|
+else
|
||
|
+ cert="$commonname.crt"
|
||
|
+ csr="$commonname.csr"
|
||
|
+ key="$commonname.key"
|
||
|
+ pem="$commonname.pem"
|
||
|
+ pfx="$commonname.p12"
|
||
|
+fi
|
||
|
+
|
||
|
+# Generate the subject's certificate. Set the X.509v3 basic constraints.
|
||
|
+if ! test -s "$cert" ; then
|
||
|
+ # Generate another key, unless we have a key or CSR.
|
||
|
+ if ! test -s "$key" && ! test -s "$csr" ; then
|
||
|
+ umask=`umask -p`
|
||
|
+ umask 077
|
||
|
+ keygen "$commonname" > "$key" 2> /dev/null
|
||
|
+ $umask
|
||
|
+ else
|
||
|
+ echo "You already have a $key or $csr file; not replacing."
|
||
|
+ done=echo
|
||
|
+ fi
|
||
|
+
|
||
|
+ if ! test -s "$csr" ; then
|
||
|
+ sed -i -e 's,^\[req_issued\]$,\[req\],g' `pwd`/openssl.cnf
|
||
|
+ openssl req -config `pwd`/openssl.cnf -new -key "$key" > "$csr" 2> /dev/null
|
||
|
+ sed -i -e 's,^\[req\]$,\[req_issued\],g' `pwd`/openssl.cnf
|
||
|
+ fi
|
||
|
+ openssl ca -batch -config `pwd`/openssl.cnf -extensions v3_issued -preserveDN -in "$csr" -days $DAYS -out "$cert" 2> /dev/null
|
||
|
+ openssl x509 -noout -text -in "$cert" > "$cert.txt"
|
||
|
+ cat "$cert" >> "$cert.txt"
|
||
|
+ cat "$cert.txt" > "$cert"
|
||
|
+ rm -f "$cert.txt"
|
||
|
+else
|
||
|
+ echo "You already have a $cert file; not replacing."
|
||
|
+ done=echo
|
||
|
+fi
|
||
|
+
|
||
|
+if test -s ca.chain.crt ; then
|
||
|
+ chain=ca.chain.crt
|
||
|
+else
|
||
|
+ chain=ca.crt
|
||
|
+fi
|
||
|
+if test "x$CA" = xTRUE ; then
|
||
|
+ cat "$chain" "$cert" > "$commonname/ca.chain.crt"
|
||
|
+fi
|
||
|
+
|
||
|
+# Create ca.pem and the subject's name.pem for the benefit of applications
|
||
|
+# which expect both the private key and the certificate in one file.
|
||
|
+umask=`umask -p`
|
||
|
+umask 077
|
||
|
+if ! test -s ca.pem ; then
|
||
|
+ cat ca.key ca.crt > ca.pem
|
||
|
+else
|
||
|
+ echo "You already have a ca.pem file; not replacing."
|
||
|
+ done=echo
|
||
|
+fi
|
||
|
+if ! test -s "$pem" ; then
|
||
|
+ cat "$key" "$cert" > "$pem"
|
||
|
+else
|
||
|
+ echo "You already have a $pem file; not replacing."
|
||
|
+ done=echo
|
||
|
+fi
|
||
|
+if ! test -s "$pfx" ; then
|
||
|
+ #openssl pkcs12 -export -inkey "$key" -in "$cert" -name "$commonname" -out "$pfx" -nodes -passout pass:qweqwe
|
||
|
+ openssl pkcs12 -export -inkey "$key" -in "$cert" -name "$commonname" -out "$pfx" -nodes -passout pass:
|
||
|
+else
|
||
|
+ echo "You already have a $pfx file; not replacing."
|
||
|
+ done=echo
|
||
|
+fi
|
||
|
+$umask
|
||
|
+$done
|
||
|
+
|
||
|
+echo CA certificate:
|
||
|
+openssl x509 -noout -issuer -in ca.crt | sed s,=\ ,\ ,g
|
||
|
+openssl x509 -noout -subject -in ca.crt | sed s,=\ ,\ ,g
|
||
|
+echo
|
||
|
+echo End entity certificate:
|
||
|
+openssl x509 -noout -issuer -in "$cert" | sed s,=\ ,\ ,g
|
||
|
+openssl x509 -noout -subject -in "$cert" | sed s,=\ ,\ ,g
|
||
|
+openssl x509 -noout -serial -in "$cert" | sed s,=,\ ,g
|
||
|
+echo
|
||
|
+echo PKCS12 bag:
|
||
|
+openssl pkcs12 -in "$pfx" -nodes -nokeys -nocerts -info -passin pass:
|
||
|
+#openssl pkcs12 -in "$pfx" -nodes -nokeys -nocerts -info -passin pass:qweqwe
|
||
|
+echo
|
||
|
+echo Verifying:
|
||
|
+echo + openssl verify -CAfile "$chain" "$cert"
|
||
|
+openssl verify -CAfile "$chain" "$cert"
|
||
|
diff --git a/shim.c b/shim.c
|
||
|
index 8130ed8..4d490b9 100644
|
||
|
--- a/shim.c
|
||
|
+++ b/shim.c
|
||
|
@@ -40,6 +40,7 @@
|
||
|
#include "shim.h"
|
||
|
#include "signature.h"
|
||
|
#include "netboot.h"
|
||
|
+#include "shim_cert.h"
|
||
|
|
||
|
#define SECOND_STAGE L"\\grub.efi"
|
||
|
#define MOK_MANAGER L"\\MokManager.efi"
|
||
|
@@ -415,6 +416,8 @@ static BOOLEAN secure_mode (void)
|
||
|
UINT8 sb, setupmode;
|
||
|
UINT32 attributes;
|
||
|
|
||
|
+ return TRUE;
|
||
|
+
|
||
|
if (insecure_mode)
|
||
|
return FALSE;
|
||
|
|
||
|
@@ -696,6 +699,19 @@ static EFI_STATUS verify_buffer (char *data, int datasize,
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
+ * Check against the shim build key
|
||
|
+ */
|
||
|
+ if (AuthenticodeVerify(cert->CertData,
|
||
|
+ context->SecDir->Size - sizeof(cert->Hdr),
|
||
|
+ shim_cert, sizeof(shim_cert), sha256hash,
|
||
|
+ SHA256_DIGEST_SIZE)) {
|
||
|
+ status = EFI_SUCCESS;
|
||
|
+ Print(L"Binary is verified by the vendor certificate\n");
|
||
|
+ return status;
|
||
|
+ }
|
||
|
+
|
||
|
+
|
||
|
+ /*
|
||
|
* And finally, check against shim's built-in key
|
||
|
*/
|
||
|
if (AuthenticodeVerify(cert->CertData,
|
||
|
@@ -1180,12 +1196,8 @@ EFI_STATUS init_grub(EFI_HANDLE image_handle)
|
||
|
|
||
|
efi_status = start_image(image_handle, SECOND_STAGE);
|
||
|
|
||
|
- if (efi_status != EFI_SUCCESS) {
|
||
|
- if (efi_status == EFI_ACCESS_DENIED)
|
||
|
- efi_status = start_image(image_handle, MOK_MANAGER);
|
||
|
- else
|
||
|
- Print(L"Failed to start grub\n");
|
||
|
- }
|
||
|
+ if (efi_status != EFI_SUCCESS)
|
||
|
+ efi_status = start_image(image_handle, MOK_MANAGER);
|
||
|
done:
|
||
|
|
||
|
return efi_status;
|
||
|
--
|
||
|
1.7.10.4
|
||
|
|
||
|
|
||
|
From 9c0c64ebde4ec504fc4e4d92ea18b889b1ccd498 Mon Sep 17 00:00:00 2001
|
||
|
From: Matthew Garrett <mjg59@srcf.ucam.org>
|
||
|
Date: Tue, 27 Nov 2012 23:52:27 -0500
|
||
|
Subject: [PATCH 2/2] Remove debug code
|
||
|
|
||
|
secure_mode() was altered to always return true for debug purposes, and this
|
||
|
accidentally got committed to mainline. Fix that.
|
||
|
---
|
||
|
shim.c | 2 --
|
||
|
1 file changed, 2 deletions(-)
|
||
|
|
||
|
diff --git a/shim.c b/shim.c
|
||
|
index 4d490b9..c3aae9e 100644
|
||
|
--- a/shim.c
|
||
|
+++ b/shim.c
|
||
|
@@ -416,8 +416,6 @@ static BOOLEAN secure_mode (void)
|
||
|
UINT8 sb, setupmode;
|
||
|
UINT32 attributes;
|
||
|
|
||
|
- return TRUE;
|
||
|
-
|
||
|
if (insecure_mode)
|
||
|
return FALSE;
|
||
|
|
||
|
--
|
||
|
1.7.10.4
|
||
|
|