Skip to content

Commit

Permalink
calculate SignerID in signeridByKey instead of relying on oesign
Browse files Browse the repository at this point in the history
  • Loading branch information
thomasten committed Jan 31, 2024
1 parent 1918bd0 commit cd5fc98
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 531 deletions.
45 changes: 26 additions & 19 deletions ego/cli/signerid.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,47 +8,54 @@ package cli

import (
"bytes"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/hex"
"encoding/pem"
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"

"ego/internal/launch"
"golang.org/x/exp/slices"
)

const (
modulusSize = 384

offsetSigstruct = 144
offsetModulus = 128
offsetMRENCLAVE = 960
)

func (c *Cli) signeridByKey(path string) (string, error) {
outBytes, err := c.runner.Output(exec.Command(c.getOesignPath(), "signerid", "-k", path))
out := string(outBytes)
if err == nil {
return out, nil
// get RSA key from PEM file
pemBytes, err := c.fs.ReadFile(path)
if err != nil {
return "", fmt.Errorf("reading key file: %w", err)
}

if err, ok := err.(*exec.ExitError); ok {
// oesign tends to print short errors to stderr and logs to stdout
if len(err.Stderr) > 0 {
return "", errors.New(string(err.Stderr))
}
fmt.Fprintln(os.Stderr, out)
if strings.Contains(out, launch.ErrOECrypto.Error()) {
return "", launch.ErrOECrypto
}
block, _ := pem.Decode(pemBytes)
if block == nil {
return "", errors.New("failed to decode PEM")
}
key, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return "", fmt.Errorf("parsing public key: %w", err)
}
rsaKey, ok := key.(*rsa.PublicKey)
if !ok {
return "", fmt.Errorf("expected RSA public key, got %T", key)
}

return "", err
// MRSIGNER is the sha256 of the modulus in little endian
n := rsaKey.N.FillBytes(make([]byte, modulusSize))
slices.Reverse(n)
sum := sha256.Sum256(n)
return hex.EncodeToString(sum[:]), nil
}

func (c *Cli) signeridByExecutable(path string) (string, error) {
const modulusSize = 384
modulus, err := c.readDataFromELF(path, oeinfoSectionName, offsetSigstruct+offsetModulus, modulusSize)
if err != nil {
return "", err
Expand Down
57 changes: 24 additions & 33 deletions ego/cli/signerid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
package cli

import (
"errors"
"os/exec"
"path/filepath"
"testing"

"github.com/spf13/afero"
Expand Down Expand Up @@ -54,39 +51,33 @@ func TestSigneridByExecutable(t *testing.T) {
}

func TestSigneridByKey(t *testing.T) {
assert := assert.New(t)

cli := NewCli(signeridRunner{}, afero.NewMemMapFs())

res, err := cli.Signerid("foo.pem")
assert.NoError(err)
assert.Equal("id foo.pem", res)
}
// generated by `openssl genrsa -3 3072 | openssl rsa -pubout`
const pubkey = `-----BEGIN PUBLIC KEY-----
MIIBoDANBgkqhkiG9w0BAQEFAAOCAY0AMIIBiAKCAYEA0+9/xzM9twAG6CuQf7LM
5Lx88UG5+y7dNqGT6RtduNi0FMBEUzlKfMkXTXDusl5c3SQKN7HXLr93W9SQ3+5m
60r+PkmylgYG+U3n2xyt0WZ+tQOigyfwQIPukxLQVMlqCu+BdxxnDjay+Xq23U+g
QsMXCfgsZtOCDnqA7yUEueRcPmrmtbQOqjtE3b6YMp0sPCYZ+zGfKUUEirUOEiD3
TdUGTjLvx0Wc+swLewhM5NLxX9zNVAGqFG23SAkvMfGXC975FQc9PwZhAkD2RqHm
UL4mcut6z8c2TEstde7jKUziiUv6nVGjQ+RsIk8gbpvGIgg2U1WHyy1pjvD61mBk
Stm3+7uzQnWtj0NjLfdvJvLj/R3idafzb0RfgNUbNlfMTg0Sx/yt5W4cu1d/5evx
CQZ6NKedMmT53RSwRk2PNKE4rzR7uED2k7SVW226/jgpeV6myL9Qp5yZq2hkQojV
fEt/+v8tVFz7f/SRw1Ps7yUzM7cuZaXEE+jQDuAp22ThAgED
-----END PUBLIC KEY-----`
const expected = "af03bba19883bea794bb72d0213d6088a828af3f7f056c2b24808e1677766e50"

type signeridRunner struct{}
assert := assert.New(t)
require := require.New(t)

func (signeridRunner) Run(cmd *exec.Cmd) error {
panic(cmd.Path)
}
fs := afero.Afero{Fs: afero.NewMemMapFs()}
cli := NewCli(nil, fs)
const filename = "foo.pem"

func (signeridRunner) Output(cmd *exec.Cmd) ([]byte, error) {
if filepath.Base(cmd.Path) != "ego-oesign" || len(cmd.Args) != 4 {
return nil, errors.New("unexpected cmd")
}
if cmd.Args[1] == "signerid" && cmd.Args[2] == "-k" {
return []byte("id " + cmd.Args[3]), nil
}
if cmd.Args[1] == "eradump" && cmd.Args[2] == "-e" {
path := cmd.Args[3]
return []byte(`{"uniqueid":"uid ` + path + `","signerid":"sid ` + path + `"}`), nil
}
return nil, errors.New("unexpected subcommand")
}
_, err := cli.Signerid(filename)
assert.Error(err)

func (signeridRunner) CombinedOutput(cmd *exec.Cmd) ([]byte, error) {
panic(cmd.Path)
}
require.NoError(fs.WriteFile(filename, []byte(pubkey), 0))

func (signeridRunner) ExitCode(cmd *exec.Cmd) int {
panic(cmd.Path)
res, err := cli.Signerid(filename)
require.NoError(err)
assert.Equal(expected, res)
}
31 changes: 16 additions & 15 deletions ego/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,33 @@ module ego
go 1.19

require (
github.com/edgelesssys/marblerun v1.2.0
github.com/google/go-cmp v0.5.9
github.com/klauspost/cpuid/v2 v2.2.5
github.com/spf13/afero v1.9.5
github.com/spf13/cobra v1.7.0
github.com/edgelesssys/marblerun v1.4.0
github.com/google/go-cmp v0.6.0
github.com/klauspost/cpuid/v2 v2.2.6
github.com/spf13/afero v1.11.0
github.com/spf13/cobra v1.8.0
github.com/stretchr/testify v1.8.4
google.golang.org/grpc v1.57.0
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a
google.golang.org/grpc v1.61.0
)

require (
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/edgelesssys/ego v1.4.0 // indirect
github.com/edgelesssys/ego v1.4.1 // indirect
github.com/edgelesssys/era v0.3.3 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/crypto v0.12.0 // indirect
golang.org/x/net v0.14.0 // indirect
golang.org/x/sys v0.11.0 // indirect
golang.org/x/text v0.12.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 // indirect
google.golang.org/protobuf v1.31.0 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/net v0.20.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe // indirect
google.golang.org/protobuf v1.32.0 // indirect
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading

0 comments on commit cd5fc98

Please sign in to comment.