File shim-local-key-sign-mokmanager.patch of Package shim

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

openSUSE Build Service is sponsored by