Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for signing EFI executable with certificate chain #19

Open
edgrz opened this issue Jan 25, 2024 · 7 comments
Open

Support for signing EFI executable with certificate chain #19

edgrz opened this issue Jan 25, 2024 · 7 comments

Comments

@edgrz
Copy link

edgrz commented Jan 25, 2024

Hello,

We are using go-uefi library to generate UEFI executables in order to achieve Secure Boot on our systems. However, our UKI certificate we want to provide for creating the Signature is a certificate bundle/chain. However, as it is now it only supports to pass a single certificate object:

SignEFIExecutable

func CreateSignature(ctx *PECOFFSigningContext, Cert *x509.Certificate, Key crypto.Signer) ([]byte, error) {
	// Tianocore demands that we pad to 8 bytes
	// They also need to be added to the checksum file
	// We move this out of the checksum function since this padding is
	// only applied to the checksums used in the signature.
	paddingBytes, _ := PaddingBytes(len(ctx.PEFile), 8)
	ctx.PEFile = append(ctx.PEFile, paddingBytes...)
	ctx.SigData.Write(paddingBytes)

	sigCtx := &pkcs7.SigningContext{
		Cert:      Cert,
		KeySigner: Key,
		SigData:   ctx.SigData.Bytes(),
		Indirect:  true,
	}

	sd, err := pkcs7.SignData(sigCtx)
	if err != nil {
		return nil, err
	}
	return sd, nil
}

Is there a way we could provide a certificate chain?

@Foxboron
Copy link
Owner

I've been reworking the signing code recently so the linked code is soon obsolete.

https://github.com/Foxboron/go-uefi/blob/master/authenticode/authenticode.go#L128

If you give a complete example on how you would like this to work, I can try and work something out. But I would need help to validate the behaviour.

@edgrz
Copy link
Author

edgrz commented Jan 26, 2024

Hi @Foxboron,

Thanks for the quick response. So basically, we want to generate an EFI executable providing the private key of a certificate for signing it and the certificate that needs to be embedded into the executable is not a self-signed one, so it means we need to provide the whole certificate chain (in my case just the cA and the certificate). So that, what we want is that the method for signing EFI executables (SignEFIExecutable function in the past and now SignAuthenticode) allow us to pass not a single cert *x509.Certificate but a slice of certs (or any other way you think fits here to support certificate chain).

I see you even have already parseCertificates function, so I think that if pkcs7.SignPKCS7 could support a slice or the bytes, would be already supporting it.

Regarding testing I do have baremetal hardware where i'm testing running Secure Boot system by generating my own ISOs, so I should be able to test it.

@Foxboron
Copy link
Owner

Are you expecting go-uefi to validate the certificate chain, or is this an external process?

@edgrz
Copy link
Author

edgrz commented Jan 26, 2024

Not needed.

So here a useful schema of what we want to achieve (not UEFI): https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/secure-boot-image-authentication_11.30.16.pdf (page 7)

We want to sign the UEFI executables with a certificate chain, where only the root cA is embedded into the signatureDB. So this would mean for validation that the other certificates of the chain must be embedded in the binary, so that UEFI can iterate over the chain to reach the root cA.

@Foxboron
Copy link
Owner

Unless there is an example of a properly signed binary I can compare against, or another form of example, I'm can't promise I'll look at it within any reasonable timeframe.

@defreng
Copy link

defreng commented Jan 31, 2024

Hi @Foxboron

I just learned that sbsign does support embedding multiple certificates into a signed binary... Would this help as a reference?

Usage: sbsign [options] --key <keyfile> --cert <certfile> <efi-boot-image>
Sign an EFI boot image for use with secure boot.

Options:
	--engine <eng>     use the specified engine to load the key
	--key <keyfile>    signing key (PEM-encoded RSA private key)
	--cert <certfile>  certificate (x509 certificate)
	--addcert <addcertfile> additional intermediate certificates in a file
	--detached         write a detached signature, instead of
	                    a signed binary
	--output <file>    write signed data to <file>
	                    (default <efi-boot-image>.signed,
	                    or <efi-boot-image>.pk7 for detached
	                    signatures

@Foxboron
Copy link
Owner

Ah, yes. That makes things a lot easier. Should probably have checked that myself :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants