diff --git a/attestedtls/attestederror.go b/attestedtls/attestederror.go deleted file mode 100644 index 29e7b64c..00000000 --- a/attestedtls/attestederror.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2021 Fraunhofer AISEC -// Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -package attestedtls - -import ( - ar "github.com/Fraunhofer-AISEC/cmc/attestationreport" -) - -// Struct that holds verification result additional to the error -type AttestedError struct { - err error - result ar.VerificationResult -} - -// Error returns the error message as a string. This implements the Error interface -func (err AttestedError) Error() string { - return err.err.Error() -} - -// Unwrap returns the unwrapped error -func (err AttestedError) Unwrap() error { - return err.err -} - -// NewAttestedError creates an AttestedError using the provided error and attestation report -func NewAttestedError(r ar.VerificationResult, err error) AttestedError { - return AttestedError{ - err: err, - result: r, - } -} - -// GetVerificationResult returns the verification result stored in the AttestedError -func (err AttestedError) GetVerificationResult() ar.VerificationResult { - return err.result -} diff --git a/attestedtls/coap.go b/attestedtls/coap.go index 9c5e54e2..d2d5d040 100644 --- a/attestedtls/coap.go +++ b/attestedtls/coap.go @@ -52,7 +52,7 @@ func (a CoapApi) obtainAR(cc cmcConfig, chbindings []byte) ([]byte, error) { log.Tracef("Contacting cmcd via coap on %v", cc.cmcAddr) conn, err := udp.Dial(cc.cmcAddr) if err != nil { - return nil, fmt.Errorf("Error dialing: %w", err) + return nil, fmt.Errorf("error dialing: %w", err) } ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() @@ -99,7 +99,7 @@ func (a CoapApi) verifyAR(chbindings, report []byte, cc cmcConfig) error { log.Tracef("Contacting cmcd via coap on %v", cc.cmcAddr) conn, err := udp.Dial(cc.cmcAddr) if err != nil { - return fmt.Errorf("Error dialing: %w", err) + return fmt.Errorf("error dialing: %w", err) } ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() @@ -144,7 +144,7 @@ func (a CoapApi) verifyAR(chbindings, report []byte, cc cmcConfig) error { // check results if !cc.result.Success { - return NewAttestedError(*cc.result, errors.New("verification failed")) + return errors.New("attestation report verification failed") } return nil @@ -158,7 +158,7 @@ func (a CoapApi) fetchSignature(cc cmcConfig, digest []byte, opts crypto.SignerO log.Tracef("Contacting cmcd via coap on %v", cc.cmcAddr) conn, err := udp.Dial(cc.cmcAddr) if err != nil { - return nil, fmt.Errorf("Error dialing: %w", err) + return nil, fmt.Errorf("error dialing: %w", err) } ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() @@ -212,7 +212,7 @@ func (a CoapApi) fetchCerts(cc cmcConfig) ([][]byte, error) { log.Tracef("Contacting cmcd via coap on %v", cc.cmcAddr) conn, err := udp.Dial(cc.cmcAddr) if err != nil { - return nil, fmt.Errorf("Error dialing: %w", err) + return nil, fmt.Errorf("error dialing: %w", err) } ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() diff --git a/attestedtls/grpc.go b/attestedtls/grpc.go index 46898b06..3e237571 100644 --- a/attestedtls/grpc.go +++ b/attestedtls/grpc.go @@ -121,7 +121,7 @@ func (a GrpcApi) verifyAR(chbindings, report []byte, cc cmcConfig) error { // check results if !cc.result.Success { - return NewAttestedError(*cc.result, errors.New("verification failed")) + return errors.New("attestation report verification failed") } return nil } diff --git a/attestedtls/libapi.go b/attestedtls/libapi.go index fbcb1b3c..36e04cc2 100644 --- a/attestedtls/libapi.go +++ b/attestedtls/libapi.go @@ -73,7 +73,7 @@ func (a LibApi) verifyAR(chbindings, report []byte, cc cmcConfig) error { } if !result.Success { - return NewAttestedError(result, errors.New("verification failed")) + return errors.New("attestation report verification failed") } return nil } diff --git a/attestedtls/socket.go b/attestedtls/socket.go index 2dcff773..af3748f2 100644 --- a/attestedtls/socket.go +++ b/attestedtls/socket.go @@ -46,7 +46,7 @@ func (a SocketApi) obtainAR(cc cmcConfig, chbindings []byte) ([]byte, error) { log.Tracef("Contacting cmcd via %v on %v", cc.network, cc.cmcAddr) conn, err := net.Dial(cc.network, cc.cmcAddr) if err != nil { - return nil, fmt.Errorf("Error dialing: %w", err) + return nil, fmt.Errorf("error dialing: %w", err) } req := &api.AttestationRequest{ @@ -88,7 +88,7 @@ func (a SocketApi) verifyAR(chbindings, report []byte, cc cmcConfig) error { log.Tracef("Contacting cmcd via %v on %v", cc.network, cc.cmcAddr) conn, err := net.Dial(cc.network, cc.cmcAddr) if err != nil { - return fmt.Errorf("Error dialing: %w", err) + return fmt.Errorf("error dialing: %w", err) } // Create Verification request @@ -133,7 +133,7 @@ func (a SocketApi) verifyAR(chbindings, report []byte, cc cmcConfig) error { // Check results if !cc.result.Success { - return NewAttestedError(*cc.result, errors.New("verification failed")) + return errors.New("attestation report verification failed") } return nil } @@ -144,7 +144,7 @@ func (a SocketApi) fetchSignature(cc cmcConfig, digest []byte, opts crypto.Signe log.Tracef("Contacting cmcd via %v on %v", cc.network, cc.cmcAddr) conn, err := net.Dial(cc.network, cc.cmcAddr) if err != nil { - return nil, fmt.Errorf("Error dialing: %w", err) + return nil, fmt.Errorf("error dialing: %w", err) } hash, err := api.SignerOptsToHash(opts) @@ -196,7 +196,7 @@ func (a SocketApi) fetchCerts(cc cmcConfig) ([][]byte, error) { log.Tracef("Contacting cmcd via %v on %v", cc.network, cc.cmcAddr) conn, err := net.Dial(cc.network, cc.cmcAddr) if err != nil { - return nil, fmt.Errorf("Error dialing: %w", err) + return nil, fmt.Errorf("error dialing: %w", err) } // Create TLS certificate request diff --git a/testtool/internal.go b/testtool/internal.go index 5d53958d..9ebb5bad 100644 --- a/testtool/internal.go +++ b/testtool/internal.go @@ -23,13 +23,12 @@ import ( "crypto/tls" "crypto/x509" "encoding/json" - "errors" "fmt" "io" "net" "net/http" "os" - "strconv" + "sync" "time" // local modules @@ -54,41 +53,18 @@ func dialInternalAddr(c *config, api atls.CmcApiSelect, addr string, tlsConf *tl atls.WithCmcNetwork(c.Network), atls.WithResult(verificationResult), atls.WithCmc(cmc)) + // Publish the attestation result asynchronously if publishing address was specified and + // the result is present + wg := new(sync.WaitGroup) + wg.Add(1) + defer wg.Wait() + go publishResultAsync(c.Publish, verificationResult, wg) if err != nil { - var attestedErr atls.AttestedError - if errors.As(err, &attestedErr) { - arresult := attestedErr.GetVerificationResult() - result, err := json.Marshal(arresult) - if err != nil { - return fmt.Errorf("internal error: failed to marshal verification result: %v", - err) - } - r, err := strconv.Unquote(string(result)) - if err != nil { - r = string(result) - } - - // Publish the attestation result if publishing address was specified - err = publishResult(c.Publish, &arresult) - if err != nil { - log.Warnf("failed to publish result: %v", err) - } - - return fmt.Errorf( - "verification Result: %v. Cannot establish connection: remote attestation failed", - r) - } return fmt.Errorf("failed to dial server: %v", err) } defer conn.Close() _ = conn.SetReadDeadline(time.Now().Add(timeoutSec * time.Second)) - // Publish the attestation result if publishing address was specified - err = publishResult(c.Publish, verificationResult) - if err != nil { - log.Warnf("failed to publish result: %v", err) - } - // Testing: write a hello string msg := "hello\n" log.Infof("Sending to peer: %v", msg) @@ -154,13 +130,13 @@ func dialInternal(c *config, api atls.CmcApiSelect, cmc *cmc.Cmc) { log.Infof("Starting monitoring with interval %v", c.interval) for { - <-ticker.C for _, addr := range c.Addr { err := dialInternalAddr(c, api, addr, tlsConf, cmc) if err != nil { log.Warnf(err.Error()) } } + <-ticker.C } } else { for _, addr := range c.Addr { @@ -233,32 +209,14 @@ func listenInternal(c *config, api atls.CmcApiSelect, cmc *cmc.Cmc) { for { log.Infof("serving under %v", addr) - // Finish TLS connection establishment with Remote Attestation + // Accept connection and perform remote attestation conn, err := ln.Accept() if err != nil { - var attestedErr atls.AttestedError - if errors.As(err, &attestedErr) { - arresult := attestedErr.GetVerificationResult() - result, err := json.Marshal(arresult) - if err != nil { - log.Errorf("Internal error: failed to marshal verification result: %v", err) - } else { - r, err := strconv.Unquote(string(result)) - if err != nil { - r = string(result) - } - - // Publish the attestation result if publishing address was specified - err = publishResult(c.Publish, &arresult) - if err != nil { - log.Warnf("failed to publish result: %v", err) - } - - log.Errorf("Verification Result: %v\n"+ - "Cannot establish connection: Remote attestation Failed.", r) - } - } else { - log.Errorf("Failed to establish connection: %v", err) + log.Errorf("Failed to establish connection: %v", err) + if c.Mtls { + // Publish the attestation result if publishing address was specified + // and result is not empty + go publishResult(c.Publish, verificationResult) } continue } @@ -268,10 +226,8 @@ func listenInternal(c *config, api atls.CmcApiSelect, cmc *cmc.Cmc) { if c.Mtls { // Publish the attestation result if publishing address was specified - err = publishResult(c.Publish, verificationResult) - if err != nil { - log.Warnf("failed to publish result: %v", err) - } + // and result is not empty + go publishResult(c.Publish, verificationResult) } } } @@ -317,13 +273,31 @@ func handleConnection(conn net.Conn) { } } -func publishResult(addr string, result *ar.VerificationResult) error { +func publishResultAsync(addr string, result *ar.VerificationResult, wg *sync.WaitGroup) { + defer wg.Done() + publishResult(addr, result) +} + +func publishResult(addr string, result *ar.VerificationResult) { + + log.Tracef("Publishing result to %v", addr) + + if result.Prover == "" { + log.Trace("Will not publish result: prover is empty (this happens if connection could not be established)") + return + } + data, err := json.Marshal(*result) if err != nil { - return fmt.Errorf("failed to marshal result: %w", err) + log.Tracef("Failed to marshal result: %v", err) + return } - return publish(addr, data) + err = publish(addr, data) + if err != nil { + log.Tracef("Failed to publish: %v", err) + return + } } func publish(addr string, result []byte) error {