github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/tao/net_test.go (about)

     1  //  Copyright (c) 2015, Google Inc.  All rights reserved.
     2  //
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  //     http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package tao
    15  
    16  import (
    17  	"bytes"
    18  	"crypto/rand"
    19  	"crypto/tls"
    20  	"crypto/x509"
    21  	"crypto/x509/pkix"
    22  	"net"
    23  	"os"
    24  	"testing"
    25  
    26  	"github.com/jlmucb/cloudproxy/go/util"
    27  )
    28  
    29  func newNetKeys(t *testing.T, ta Tao, org string) (*Keys, *tls.Config) {
    30  	var keys *Keys
    31  	var err error
    32  	if ta != nil {
    33  		keys, err = NewTemporaryTaoDelegatedKeys(Signing, ta)
    34  	} else {
    35  		keys, err = NewTemporaryKeys(Signing)
    36  	}
    37  	if err != nil {
    38  		t.Fatalf("couldn't create new temporary delegated keys: %s", err)
    39  	}
    40  
    41  	signerAlg := SignerTypeFromSuiteName(TaoCryptoSuite)
    42  	if signerAlg == nil {
    43  		t.Error("Cant get signer alg from ciphersuite")
    44  	}
    45  	pkInt := PublicKeyAlgFromSignerAlg(*signerAlg)
    46  	skInt := SignatureAlgFromSignerAlg(*signerAlg)
    47  	if pkInt < 0 || skInt < 0 {
    48  		t.Error("Cant get x509 signer alg from signer alg")
    49  	}
    50  	keys.Cert, err = keys.SigningKey.CreateSelfSignedX509(pkInt, skInt, 1,
    51  		&pkix.Name{
    52  		Organization: []string{org}})
    53  	if err != nil {
    54  		t.Fatalf("couldn't create a self-signed certificate from the keys: %s", err)
    55  	}
    56  
    57  	tlsc, err := EncodeTLSCert(keys)
    58  	if err != nil {
    59  		t.Fatalf("couldn't encode TLS cert from the keys")
    60  	}
    61  
    62  	conf := &tls.Config{
    63  		RootCAs:            x509.NewCertPool(),
    64  		Certificates:       []tls.Certificate{*tlsc},
    65  		InsecureSkipVerify: true,
    66  		ClientAuth:         tls.RequireAnyClientCert,
    67  	}
    68  
    69  	return keys, conf
    70  }
    71  
    72  func setUpListener(t *testing.T, anonymous bool) (net.Listener, *Keys, Tao) {
    73  	st, err := NewSoftTao("", nil)
    74  	if err != nil {
    75  		t.Fatalf("couldn't create a new SoftTao: %s", err)
    76  	}
    77  
    78  	soft, ok := st.(*SoftTao)
    79  	if !ok {
    80  		t.Fatalf("couldn't down-cast the Tao to a SoftTao")
    81  	}
    82  
    83  	keys, conf := newNetKeys(t, st, "Net Test")
    84  
    85  	// For a simple Listen test, use the LiberalGuard.
    86  	var l net.Listener
    87  	if !anonymous {
    88  		l, err = Listen("tcp", "127.0.0.1:0", conf, LiberalGuard, soft.GetVerifier(), keys.Delegation)
    89  	} else {
    90  		l, err = ListenAnonymous("tcp", "127.0.0.1:0", conf, LiberalGuard, soft.GetVerifier(), keys.Delegation)
    91  	}
    92  	if err != nil {
    93  		t.Fatalf("couldn't set up a Tao listener: %s", err)
    94  	}
    95  
    96  	return l, keys, st
    97  }
    98  
    99  func TestListener(t *testing.T) {
   100  	// Run a basic test to make sure the listener can be created.
   101  	l, _, _ := setUpListener(t, false)
   102  	l.Close()
   103  }
   104  
   105  func TestAnonymousListener(t *testing.T) {
   106  	// Run a basic test to make sure the anonymousListener can be created.
   107  	l, _, _ := setUpListener(t, true)
   108  	l.Close()
   109  }
   110  
   111  // getMessage gets all the bytes of a message, using a fixed-size buffer.
   112  func getMessage(t *testing.T, c net.Conn, count int) []byte {
   113  	b := make([]byte, count)
   114  	n, err := c.Read(b)
   115  	if err != nil {
   116  		t.Fatalf("couldn't read from the connection: %s", err)
   117  	}
   118  	if n != count {
   119  		t.Fatalf("failed to read the right number of bytes: expected %d, but got %d", count, n)
   120  	}
   121  
   122  	return b
   123  }
   124  
   125  // runListener accepts a single connection and echo the message received on it.
   126  // This function takes ownership of the net.Listener and closes it.
   127  func runListener(t *testing.T, l net.Listener, count int, ch chan<- bool) {
   128  	defer l.Close()
   129  	c, err := l.Accept()
   130  	if err != nil {
   131  		t.Fatalf("couldn't accept a network connection: %s", err)
   132  	}
   133  	defer c.Close()
   134  	msg := getMessage(t, c, count)
   135  
   136  	if _, err := c.Write(msg); err != nil {
   137  		t.Fatalf("couldn't write the bytes back on the connection: %s", err)
   138  	}
   139  
   140  	ch <- true
   141  }
   142  
   143  // Test TLS handshake between two Tao-delegated peers.
   144  func TestTaoHandshake(t *testing.T) {
   145  	l, _, st := setUpListener(t, false)
   146  	addr := l.Addr()
   147  	ch := make(chan bool)
   148  
   149  	count := 16
   150  	go runListener(t, l, count, ch)
   151  
   152  	// Create a client to connect to the server and send and receive a
   153  	// message.
   154  	verifier := st.(*SoftTao).GetVerifier()
   155  
   156  	ck, _ := newNetKeys(t, st, "Net Test")
   157  
   158  	c, err := Dial("tcp", addr.String(), LiberalGuard, verifier, ck)
   159  	if err != nil {
   160  		t.Fatalf("couldn't dial the server using Tao networking: %s", err)
   161  	}
   162  
   163  	b := make([]byte, count)
   164  	if _, err := rand.Read(b); err != nil {
   165  		t.Fatalf("couldn't read bytes to send to the server: %s", err)
   166  	}
   167  
   168  	if _, err := c.Write(b); err != nil {
   169  		t.Fatalf("couldn't send the bytes to the server: %s", err)
   170  	}
   171  
   172  	res := getMessage(t, c, count)
   173  	if !bytes.Equal(res, b) {
   174  		t.Fatal("the received bytes didn't match the original bytes")
   175  	}
   176  
   177  	// Wait for the server to finish.
   178  	<-ch
   179  }
   180  
   181  // Test TLS handshake between a Tao-delegated server and anonymous client.
   182  func TestAnonymousTaoHandshake(t *testing.T) {
   183  	l, _, st := setUpListener(t, true)
   184  	addr := l.Addr()
   185  	ch := make(chan bool)
   186  
   187  	count := 16
   188  	go runListener(t, l, count, ch)
   189  
   190  	// Create a client to connect to the server and send and receive a
   191  	// message.
   192  	verifier := st.(*SoftTao).GetVerifier()
   193  
   194  	c, err := Dial("tcp", addr.String(), LiberalGuard, verifier, nil)
   195  	if err != nil {
   196  		t.Fatalf("couldn't dial the server using Tao networking: %s", err)
   197  	}
   198  
   199  	b := make([]byte, count)
   200  	if _, err := rand.Read(b); err != nil {
   201  		t.Fatalf("couldn't read bytes to send to the server: %s", err)
   202  	}
   203  
   204  	if _, err := c.Write(b); err != nil {
   205  		t.Fatalf("couldn't send the bytes to the server: %s", err)
   206  	}
   207  
   208  	res := getMessage(t, c, count)
   209  	if !bytes.Equal(res, b) {
   210  		t.Fatal("the received bytes didn't match the original bytes")
   211  	}
   212  
   213  	// Wait for the server to finish.
   214  	<-ch
   215  }
   216  
   217  func runTCCA(t *testing.T, l net.Listener, pk *Keys, g Guard, ch chan<- bool) {
   218  	conn, err := l.Accept()
   219  	if err != nil {
   220  		t.Fatalf("couldn't accept a connection for tcca: %s", err)
   221  	}
   222  
   223  	HandleCARequest(conn, pk.SigningKey, g)
   224  	ch <- true
   225  }
   226  
   227  func TestCARequestAttestation(t *testing.T) {
   228  	// Create a temporary key as the policy key.
   229  	pk, err := NewTemporaryKeys(Signing)
   230  	if err != nil {
   231  		t.Fatalf("couldn't set up a temporary policy key: %s", err)
   232  	}
   233  
   234  	cal, err := net.Listen("tcp", "127.0.0.1:0")
   235  	caAddr := cal.Addr()
   236  
   237  	// For the simple test, use a LiberalGuard in the CA.
   238  	ch := make(chan bool)
   239  	go runTCCA(t, cal, pk, LiberalGuard, ch)
   240  
   241  	// Set up some keys to be attested.
   242  	st, err := NewSoftTao("", nil)
   243  	if err != nil {
   244  		t.Fatalf("couldn't create a new SoftTao: %s", err)
   245  	}
   246  
   247  	keys, _ := newNetKeys(t, st, "Net Test")
   248  
   249  	_, err = RequestAttestation("tcp", caAddr.String(), keys, pk.VerifyingKey)
   250  	if err != nil {
   251  		t.Fatalf("failed to get an attestation from the CA: %s", err)
   252  	}
   253  
   254  	// Wait for the CA to finish
   255  	<-ch
   256  }
   257  
   258  func TestCARequestTruncatedAttestation(t *testing.T) {
   259  	// Create a temporary key as the policy key.
   260  
   261  	pk, err := NewTemporaryKeys(Signing)
   262  	if err != nil {
   263  		t.Fatalf("couldn't set up a temporary policy key: %s", err)
   264  	}
   265  
   266  	cal, err := net.Listen("tcp", "127.0.0.1:0")
   267  	caAddr := cal.Addr()
   268  
   269  	// For the simple test, use a LiberalGuard in the CA.
   270  	ch := make(chan bool)
   271  	go runTCCA(t, cal, pk, LiberalGuard, ch)
   272  
   273  	// Set up some keys to be attested.
   274  	st, err := NewSoftTao("", nil)
   275  	if err != nil {
   276  		t.Fatalf("couldn't create a new SoftTao: %s", err)
   277  	}
   278  
   279  	keys, _ := newNetKeys(t, st, "Net Test")
   280  
   281  	_, err = RequestTruncatedAttestation("tcp", caAddr.String(), keys, pk.VerifyingKey)
   282  	if err != nil {
   283  		t.Fatalf("failed to get a truncated attestation from the CA: %s", err)
   284  	}
   285  
   286  	// Wait for the CA to finish
   287  	<-ch
   288  }
   289  
   290  func TestCARequestDatalogRules(t *testing.T) {
   291  	cal, err := net.Listen("tcp", "127.0.0.1:0")
   292  	caAddr := cal.Addr()
   293  
   294  	guard, keys, tmpDir, err := makeDatalogGuard()
   295  	if err != nil {
   296  		os.RemoveAll(tmpDir)
   297  		t.Fatal(err)
   298  	}
   299  	defer os.RemoveAll(tmpDir)
   300  	ch := make(chan bool)
   301  
   302  	// Nominal test
   303  	go runTCCA(t, cal, keys, guard, ch)
   304  	_, err = RequestDatalogRules("tcp", caAddr.String(), keys.VerifyingKey)
   305  	if err != nil {
   306  		t.Errorf("Failed to get datalog rules from CA: %s", err)
   307  	}
   308  	<-ch
   309  
   310  	// Signature shouldn't verify
   311  	badKeys, _ := NewTemporaryKeys(Signing)
   312  	go runTCCA(t, cal, badKeys, guard, ch)
   313  	_, err = RequestDatalogRules("tcp", caAddr.String(), keys.VerifyingKey)
   314  	if err == nil {
   315  		t.Error("Signature verified, should have failed")
   316  	} else {
   317  		t.Logf("Signature invalid!, %s", err)
   318  	}
   319  	<-ch
   320  }
   321  
   322  func TestCARequestACLSet(t *testing.T) {
   323  	cal, err := net.Listen("tcp", "127.0.0.1:0")
   324  	caAddr := cal.Addr()
   325  
   326  	// Run TaoCA with a DatalogGuard.
   327  	guard, keys, tmpDir, err := makeACLGuard()
   328  	if err != nil {
   329  		os.RemoveAll(tmpDir)
   330  		t.Fatal(err)
   331  	}
   332  	defer os.RemoveAll(tmpDir)
   333  	ch := make(chan bool)
   334  
   335  	// Nominal test.
   336  	go runTCCA(t, cal, keys, guard, ch)
   337  	_, err = RequestACLSet("tcp", caAddr.String(), keys.VerifyingKey)
   338  	if err != nil {
   339  		t.Fatalf("Failed to get ACL set from CA: %s", err)
   340  	}
   341  	<-ch
   342  
   343  	// Signature shouldn't verify
   344  	badKeys, _ := NewTemporaryKeys(Signing)
   345  	go runTCCA(t, cal, badKeys, guard, ch)
   346  	_, err = RequestACLSet("tcp", caAddr.String(), keys.VerifyingKey)
   347  	if err == nil {
   348  		t.Error("Signature verified, should have failed")
   349  	} else {
   350  		t.Logf("Signature invalid!, %s", err)
   351  	}
   352  	<-ch
   353  }
   354  
   355  func TestInvalidRequest(t *testing.T) {
   356  	cal, err := net.Listen("tcp", "127.0.0.1:0")
   357  	caAddr := cal.Addr()
   358  
   359  	guard, keys, tmpDir, err := makeDatalogGuard()
   360  	if err != nil {
   361  		os.RemoveAll(tmpDir)
   362  		t.Fatal(err)
   363  	}
   364  	defer os.RemoveAll(tmpDir)
   365  	ch := make(chan bool)
   366  
   367  	// Test an invalid request.
   368  	go runTCCA(t, cal, keys, guard, ch)
   369  
   370  	conn, err := net.Dial("tcp", caAddr.String())
   371  	if err != nil {
   372  		t.Fatal("Failed to connect to TaoCA.")
   373  	}
   374  	defer conn.Close()
   375  
   376  	// Bad CArequest, no value for bad_req.Attesation
   377  	badReq := new(CARequest)
   378  	badReq.Type = CAType_ATTESTATION.Enum()
   379  
   380  	ms := util.NewMessageStream(conn)
   381  	if _, err = ms.WriteMessage(badReq); err != nil {
   382  		t.Logf("Failed to write to message stream: %s", err)
   383  	}
   384  
   385  	// Receive response.
   386  	var resp CAResponse
   387  	if err := ms.ReadMessage(&resp); err != nil {
   388  		t.Fatalf("Failed to read from message stream: %s", err)
   389  	}
   390  
   391  	if *resp.Type != CAType_UNDEFINED {
   392  		t.Fatalf("Response should have been UNDEFINED, got %s", resp.Type.String())
   393  	}
   394  
   395  	<-ch
   396  }