Skip to content

Commit

Permalink
go/ekiden/cmd/ias: Add support at the proxy for mocking responses
Browse files Browse the repository at this point in the history
  • Loading branch information
Yawning committed Aug 22, 2019
1 parent f3f39b6 commit 6fc2622
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 28 deletions.
62 changes: 51 additions & 11 deletions go/common/sgx/ias/ias.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,31 @@ type iasEvidencePayload struct {
Nonce string `codec:"string,omitempty"`
}

type mockEndpoint struct {
spidInfo SPIDInfo
}

func (e *mockEndpoint) VerifyEvidence(ctx context.Context, quote, pseManifest []byte, nonce string) ([]byte, []byte, []byte, error) {
if len(nonce) > nonceMaxLen {
return nil, nil, nil, fmt.Errorf("ias: invalid nonce length")
}

avr, err := NewMockAVR(quote, nonce)
if err != nil {
return nil, nil, nil, errors.Wrap(err, "ias: failed to generate mock AVR")
}

return avr, nil, nil, nil
}

func (e *mockEndpoint) GetSPIDInfo(ctx context.Context) (*SPIDInfo, error) {
return &e.spidInfo, nil
}

func (e *mockEndpoint) GetSigRL(ctx context.Context, epidGID uint32) ([]byte, error) {
return nil, nil
}

// EndpointConfig is the IAS endpoint configuration.
type EndpointConfig struct {
// AuthCert is the IAS authentication certificate (and private key).
Expand All @@ -204,11 +229,35 @@ type EndpointConfig struct {
// IsProduction specifies if the endpoint should connect to the
// production endpoint.
IsProduction bool

// DebugIsMock is setif set to true will return mock AVR responses
// and not actually contact IAS.
DebugIsMock bool
}

// NewIASEndpoint returns a new Endpoint backed by an IAS server operated
// by Intel.
// NewIASEndpoint returns a new IAS endpoint.
func NewIASEndpoint(cfg *EndpointConfig) (Endpoint, error) {
spidFromHex, err := hex.DecodeString(cfg.SPID)
if err != nil {
return nil, ErrMalformedSPID
}
var spidBin SPID
if err := spidBin.UnmarshalBinary(spidFromHex); err != nil {
return nil, err
}

if cfg.DebugIsMock {
logger.Warn("DebugSkipVerify set, VerifyEvidence calls will be mocked")

SetSkipVerify() // Intel isn't signing anything.
return &mockEndpoint{
spidInfo: SPIDInfo{
SPID: spidBin,
QuoteSignatureType: cfg.QuoteSignatureType,
},
}, nil
}

tlsRoots, err := x509.SystemCertPool()
if err != nil {
return nil, errors.Wrap(err, "ias: failed to load system cert pool")
Expand Down Expand Up @@ -246,15 +295,6 @@ func NewIASEndpoint(cfg *EndpointConfig) (Endpoint, error) {
}
}

spidFromHex, err := hex.DecodeString(cfg.SPID)
if err != nil {
return nil, ErrMalformedSPID
}
var spidBin SPID
if err := spidBin.UnmarshalBinary(spidFromHex); err != nil {
return nil, err
}

e := &httpEndpoint{
httpClient: &http.Client{
Transport: &http.Transport{
Expand Down
42 changes: 25 additions & 17 deletions go/ekiden/cmd/ias/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const (
cfgSPID = "spid"
cfgQuoteSigType = "quote_signature_type"
cfgIsProduction = "production"
cfgDebugMock = "debug.mock"
)

var (
Expand Down Expand Up @@ -154,8 +155,7 @@ func doProxy(cmd *cobra.Command, args []string) {

func initProxy(env *proxyEnv) error {
cfg := &ias.EndpointConfig{
SPID: viper.GetString(cfgSPID),
IsProduction: viper.GetBool(cfgIsProduction),
SPID: viper.GetString(cfgSPID),
}

quoteSigType := viper.GetString(cfgQuoteSigType)
Expand All @@ -168,27 +168,33 @@ func initProxy(env *proxyEnv) error {
return fmt.Errorf("ias: invalid signature type: %s", quoteSigType)
}

if authCertCA := viper.GetString(cfgAuthCertCA); authCertCA != "" {
certData, err := ioutil.ReadFile(authCertCA)
if err != nil {
return err
if !viper.GetBool(cfgDebugMock) {
if authCertCA := viper.GetString(cfgAuthCertCA); authCertCA != "" {
certData, err := ioutil.ReadFile(authCertCA)
if err != nil {
return err
}

cfg.AuthCertCA, _, err = ias.CertFromPEM(certData)
if err != nil {
return err
}
}

cfg.AuthCertCA, _, err = ias.CertFromPEM(certData)
authCert, err := tls.LoadX509KeyPair(viper.GetString(cfgAuthCertFile), viper.GetString(cfgAuthKeyFile))
if err != nil {
return err
return fmt.Errorf("ias: failed to load client certificate: %s", err)
}
}
authCert.Leaf, err = x509.ParseCertificate(authCert.Certificate[0])
if err != nil {
return fmt.Errorf("ias: failed to parse client leaf certificate: %s", err)
}
cfg.AuthCert = &authCert

authCert, err := tls.LoadX509KeyPair(viper.GetString(cfgAuthCertFile), viper.GetString(cfgAuthKeyFile))
if err != nil {
return fmt.Errorf("ias: failed to load client certificate: %s", err)
}
authCert.Leaf, err = x509.ParseCertificate(authCert.Certificate[0])
if err != nil {
return fmt.Errorf("ias: failed to parse client leaf certificate: %s", err)
cfg.IsProduction = viper.GetBool(cfgIsProduction)
} else {
cfg.DebugIsMock = true
}
cfg.AuthCert = &authCert

endpoint, err := ias.NewIASEndpoint(cfg)
if err != nil {
Expand All @@ -211,6 +217,7 @@ func RegisterFlags(cmd *cobra.Command) {
cmd.Flags().String(cfgSPID, "", "SPID associated with the client certificate")
cmd.Flags().String(cfgQuoteSigType, "linkable", "quote signature type associated with the SPID")
cmd.Flags().Bool(cfgIsProduction, false, "use the production IAS endpoint")
cmd.Flags().Bool(cfgDebugMock, false, "generate mock IAS AVR responses (UNSAFE)")
}

for _, v := range []string{
Expand All @@ -220,6 +227,7 @@ func RegisterFlags(cmd *cobra.Command) {
cfgSPID,
cfgQuoteSigType,
cfgIsProduction,
cfgDebugMock,
} {
_ = viper.BindPFlag(v, cmd.Flags().Lookup(v))
}
Expand Down

0 comments on commit 6fc2622

Please sign in to comment.