Skip to content

Commit

Permalink
Fix Marble verification with Coordinator root certificate (#782)
Browse files Browse the repository at this point in the history
* Fix Marble verification with Coordinator root certificate

* fix lint
  • Loading branch information
thomasten authored Jan 8, 2025
1 parent 9b4066f commit b876f1a
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 17 deletions.
9 changes: 6 additions & 3 deletions cmd/marble-test/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ func main() {
if len(os.Args) > 1 {
switch os.Args[1] {
case "serve":
runServer(addr)
runServer(addr, true)
return
case "serve-no-client-auth":
runServer(addr, false)
return
case "monotonic-counter":
if err := testMonotonicCounter(); err != nil {
Expand All @@ -41,9 +44,9 @@ func main() {
}
}

func runServer(addr string) {
func runServer(addr string, verifyClientCerts bool) {
// Retrieve server TLS config from ertgolib
tlsConfig, err := marble.GetTLSConfig(true)
tlsConfig, err := marble.GetTLSConfig(verifyClientCerts)
if err != nil {
panic(err)
}
Expand Down
24 changes: 17 additions & 7 deletions coordinator/core/marbleapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ import (
)

type reservedSecrets struct {
RootCA manifest.Secret
MarbleCert manifest.Secret
CoordinatorRoot manifest.Secret
RootCA manifest.Secret
MarbleCert manifest.Secret
CoordinatorRoot manifest.Secret
CoordinatorIntermediate manifest.Secret
}

// Defines the "MarbleRun" prefix when mentioned in a manifest.
Expand Down Expand Up @@ -368,9 +369,13 @@ func customizeParameters(params manifest.Parameters, specialSecrets reservedSecr
if err != nil {
return nil, fmt.Errorf("encoding Coordinator root CA: %w", err)
}
coordinatorIntermediatePem, err := manifest.EncodeSecretDataToPem(specialSecrets.CoordinatorIntermediate.Cert)
if err != nil {
return nil, fmt.Errorf("encoding Coordinator intermediate certificate: %w", err)
}

customParams.Env[marble.MarbleEnvironmentRootCA] = []byte(rootCaPem)
customParams.Env[marble.MarbleEnvironmentCertificateChain] = []byte(marbleCertPem + rootCaPem)
customParams.Env[marble.MarbleEnvironmentCertificateChain] = []byte(marbleCertPem + coordinatorIntermediatePem)
customParams.Env[marble.MarbleEnvironmentPrivateKey] = []byte(encodedPrivKey)
customParams.Env[globalconstants.MarbleEnvironmentCoordinatorRootCA] = []byte(coordinatorRootPem)

Expand Down Expand Up @@ -426,12 +431,17 @@ func (c *Core) generateMarbleAuthSecrets(txdata storeGetter, req *rpc.Activation
if err != nil {
return reservedSecrets{}, err
}
coordinatorIntermediateCert, err := txdata.GetCertificate(constants.SKCoordinatorIntermediateCert)
if err != nil {
return reservedSecrets{}, err
}

// customize marble's parameters
authSecrets := reservedSecrets{
RootCA: manifest.Secret{Cert: manifest.Certificate(*marbleRootCert)},
MarbleCert: manifest.Secret{Cert: manifest.Certificate(*marbleCert), Public: encodedPubKey, Private: encodedPrivKey},
CoordinatorRoot: manifest.Secret{Cert: manifest.Certificate(*coordinatorRootCert)},
RootCA: manifest.Secret{Cert: manifest.Certificate(*marbleRootCert)},
MarbleCert: manifest.Secret{Cert: manifest.Certificate(*marbleCert), Public: encodedPubKey, Private: encodedPrivKey},
CoordinatorRoot: manifest.Secret{Cert: manifest.Certificate(*coordinatorRootCert)},
CoordinatorIntermediate: manifest.Secret{Cert: manifest.Certificate(*coordinatorIntermediateCert)},
}

return authSecrets, nil
Expand Down
10 changes: 5 additions & 5 deletions coordinator/core/marbleapi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,16 +303,16 @@ func (ms *marbleSpawner) newMarble(t *testing.T, marbleType string, infraName st
pLeaf, rest := pem.Decode(params.Env[libMarble.MarbleEnvironmentCertificateChain])
ms.assert.NotNil(pLeaf)
ms.assert.NotEmpty(rest)
pMarbleRoot, rest := pem.Decode(rest)
ms.assert.NotNil(pMarbleRoot)
pIntermediate, rest := pem.Decode(rest)
ms.assert.NotNil(pIntermediate)
ms.assert.Empty(rest)

newMarbleRootCert, err := x509.ParseCertificate(pMarbleRoot.Bytes)
newIntermediateCert, err := x509.ParseCertificate(pIntermediate.Bytes)
ms.assert.NoError(err)
newLeafCert, err := x509.ParseCertificate(pLeaf.Bytes)
ms.assert.NoError(err)

ms.assert.Equal(constants.CoordinatorIntermediateName, newMarbleRootCert.Issuer.CommonName)
ms.assert.Equal(constants.CoordinatorName, newIntermediateCert.Issuer.CommonName)
ms.assert.Equal(constants.CoordinatorIntermediateName, newLeafCert.Issuer.CommonName)

// Check CommonName for leaf certificate
Expand All @@ -331,7 +331,7 @@ func (ms *marbleSpawner) newMarble(t *testing.T, marbleType string, infraName st
marbleRootCert := testutil.GetCertificate(t, ms.coreServer.txHandle, constants.SKMarbleRootCert)
// Check Signature for both, intermediate certificate and leaf certificate
ms.assert.NoError(rootCert.CheckSignature(intermediateCert.SignatureAlgorithm, intermediateCert.RawTBSCertificate, intermediateCert.Signature))
ms.assert.NoError(newMarbleRootCert.CheckSignature(newMarbleRootCert.SignatureAlgorithm, newMarbleRootCert.RawTBSCertificate, newMarbleRootCert.Signature))
ms.assert.NoError(newIntermediateCert.CheckSignature(newLeafCert.SignatureAlgorithm, newLeafCert.RawTBSCertificate, newLeafCert.Signature))
ms.assert.NoError(marbleRootCert.CheckSignature(newLeafCert.SignatureAlgorithm, newLeafCert.RawTBSCertificate, newLeafCert.Signature))

// Validate generated secret (only specified in backendFirst)
Expand Down
4 changes: 2 additions & 2 deletions marble/premain/occlum.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ import (
)

// ioctlGetQuoteSize holds the ioctl value for the SGX device to retrieve the size of the quote in bytes.
// Generated by the following macro: _IOR('s', 7, uint32_t)
// Generated by the following macro: _IOR('s', 7, uint32_t) .
const ioctlGetQuoteSize = 2147775239

// ioctlGenerateQuote holds the ioctl value for the SGX device to issue a quote.
// For the struct definition, see above.
// Generated by the following macro: _IOWR('s', 8, sgxioc_gen_dcap_quote_arg_t)
// Generated by the following macro: _IOWR('s', 8, sgxioc_gen_dcap_quote_arg_t) .
const ioctlGenerateQuote = 3222827784

// OcclumQuoteIssuer issues quotes.
Expand Down
37 changes: 37 additions & 0 deletions test/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"flag"
"log"
"net"
"net/http"
"os"
"testing"

Expand Down Expand Up @@ -379,6 +380,42 @@ func TestManifestUpdate(t *testing.T) {
assert.False(f.StartMarbleClient(f.Ctx, clientCfg), "Did start successfully, but must not run successfully. The increased minimum SecurityVersion was ignored.")
}

func TestExternalConnectionToMarble(t *testing.T) {
assert := assert.New(t)
require := require.New(t)
f := newFramework(t)

cfg := framework.NewCoordinatorConfig()
defer cfg.Cleanup()
f.StartCoordinator(f.Ctx, cfg)

_, err := f.SetManifest(f.TestManifest)
require.NoError(err)

serverCfg := framework.NewMarbleConfig(meshServerAddr, "testMarbleServerNoClientAuth", "localhost")
defer serverCfg.Cleanup()
f.StartMarbleServer(f.Ctx, serverCfg)

rootCert, intermediateCert, _, err := api.VerifyCoordinator(context.Background(), clientServerAddr, api.VerifyOptions{InsecureSkipVerify: true})
require.NoError(err)

req, err := http.NewRequestWithContext(f.Ctx, http.MethodGet, "https://"+marbleTestAddr, http.NoBody)
require.NoError(err)

// test that an external app can connect and verify with both the root and the intermediate certificate
for _, root := range []*x509.Certificate{rootCert, intermediateCert} {
roots := x509.NewCertPool()
roots.AddCert(root)
client := http.Client{Transport: &http.Transport{TLSClientConfig: &tls.Config{RootCAs: roots}}}
resp, err := client.Do(req)
assert.NoError(err)
if err == nil {
resp.Body.Close()
assert.Equal(http.StatusOK, resp.StatusCode)
}
}
}

func TestSignQuote(t *testing.T) {
if *simulationMode || *noenclave {
t.Skip("This test cannot be run in Simulation / No Enclave mode.")
Expand Down
9 changes: 9 additions & 0 deletions test/manifests.go
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,15 @@ var IntegrationManifestJSON = `{
}
}
},
"testMarbleServerNoClientAuth": {
"Package": "backend",
"Parameters": {
"Argv": [
"./marble",
"serve-no-client-auth"
]
}
},
"testMarbleMonotonicCounter": {
"Package": "backend",
"Parameters": {
Expand Down

0 comments on commit b876f1a

Please sign in to comment.