github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/apps/roughtime/server.go (about)

     1  // Copyright (c) 2016, Google Inc. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // this is an adapted version of the server code in the roughtime
    16  // for cloudproxy. this version uses Tao to listen and answer the queries.
    17  package roughtime
    18  
    19  import (
    20  	"crypto/rand"
    21  	"crypto/tls"
    22  	"crypto/x509"
    23  	"crypto/x509/pkix"
    24  	"encoding/json"
    25  	"errors"
    26  	"fmt"
    27  	"log"
    28  	"net"
    29  	"os"
    30  	"time"
    31  
    32  	"github.com/jlmucb/cloudproxy/go/apps/roughtime/agl_roughtime/config"
    33  	"github.com/jlmucb/cloudproxy/go/apps/roughtime/agl_roughtime/protocol"
    34  	"github.com/jlmucb/cloudproxy/go/tao"
    35  
    36  	"golang.org/x/crypto/ed25519"
    37  )
    38  
    39  type Server struct {
    40  	keys       *tao.Keys // Various keys for this hosted program.
    41  	publicKey  ed25519.PublicKey
    42  	privateKey ed25519.PrivateKey
    43  	domain     *tao.Domain  // Policy guard and public key.
    44  	listener   net.Listener // Socket where server listens for proxies/routers
    45  }
    46  
    47  func NewServer(path, network string, port int, x509Identity *pkix.Name, t tao.Tao) (*Server, error) {
    48  	// Generate keys and get attestation from parent.
    49  	keys, err := tao.NewTemporaryTaoDelegatedKeys(tao.Signing|tao.Crypting, t)
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  
    54  	// Create a certificate.
    55  	pkInt := tao.PublicKeyAlgFromSignerAlg(*keys.SigningKey.Header.KeyType)
    56  	sigInt := tao.SignatureAlgFromSignerAlg(*keys.SigningKey.Header.KeyType)
    57  	keys.Cert, err = keys.SigningKey.CreateSelfSignedX509(pkInt, sigInt, int64(1),
    58  		x509Identity)
    59  	if err != nil {
    60  		return nil, err
    61  	}
    62  
    63  	// Load domain from local configuration.
    64  	domain, err := tao.LoadDomain(path, nil)
    65  	if err != nil {
    66  		return nil, err
    67  	}
    68  
    69  	// Encode TLS certificate.
    70  	cert, err := tao.EncodeTLSCert(keys)
    71  	if err != nil {
    72  		return nil, err
    73  	}
    74  
    75  	pub, priv, err := ed25519.GenerateKey(rand.Reader)
    76  	if err != nil {
    77  		return nil, err
    78  	}
    79  
    80  	tlsConfig := &tls.Config{
    81  		RootCAs:            x509.NewCertPool(),
    82  		Certificates:       []tls.Certificate{*cert},
    83  		InsecureSkipVerify: true,
    84  		ClientAuth:         tls.RequestClientCert,
    85  	}
    86  
    87  	listener, err := tao.ListenAnonymous(network, fmt.Sprintf(":%d", port), tlsConfig,
    88  		domain.Guard, domain.Keys.VerifyingKey, keys.Delegation)
    89  	if err != nil {
    90  		return nil, err
    91  	}
    92  
    93  	s := &Server{
    94  		keys:       keys,
    95  		publicKey:  pub,
    96  		privateKey: priv,
    97  		domain:     domain,
    98  		listener:   listener,
    99  	}
   100  
   101  	return s, nil
   102  }
   103  
   104  func (s *Server) ServeForever() error {
   105  	onlinePublicKey, onlinePrivateKey, err := ed25519.GenerateKey(rand.Reader)
   106  	if err != nil {
   107  		return errors.New("Cannot generate private key: " + err.Error())
   108  	}
   109  
   110  	// As this is just an example, the certificate is created covering the
   111  	// maximum possible range.
   112  	cert, err := protocol.CreateCertificate(0, ^uint64(0), onlinePublicKey, s.privateKey)
   113  	if err != nil {
   114  		return errors.New("Cannot generate certificate: " + err.Error())
   115  	}
   116  
   117  	var packetBuf [protocol.MinRequestSize]byte
   118  
   119  	for {
   120  		conn, err := s.listener.Accept()
   121  		if err != nil {
   122  			log.Fatal(err)
   123  		}
   124  
   125  		n, err := conn.Read(packetBuf[:])
   126  		if err != nil {
   127  			log.Print(err)
   128  		}
   129  
   130  		if n < protocol.MinRequestSize {
   131  			continue
   132  		}
   133  
   134  		packet, err := protocol.Decode(packetBuf[:n])
   135  		if err != nil {
   136  			continue
   137  		}
   138  
   139  		nonce, ok := packet[protocol.TagNonce]
   140  		if !ok || len(nonce) != protocol.NonceSize {
   141  			continue
   142  		}
   143  
   144  		midpoint := uint64(time.Now().UnixNano() / 1000)
   145  		radius := uint32(1000000)
   146  
   147  		replies, err := protocol.CreateReplies([][]byte{nonce}, midpoint, radius, cert, onlinePrivateKey)
   148  		if err != nil {
   149  			log.Print(err)
   150  			continue
   151  		}
   152  
   153  		if len(replies) != 1 {
   154  			continue
   155  		}
   156  
   157  		conn.Write(replies[0])
   158  	}
   159  }
   160  
   161  func generateKeyPair() error {
   162  	rootPublic, rootPrivate, err := ed25519.GenerateKey(rand.Reader)
   163  	if err != nil {
   164  		return err
   165  	}
   166  
   167  	fmt.Printf("Private key: %x\n\n", rootPrivate)
   168  
   169  	exampleConfig := config.ServersJSON{
   170  		Servers: []config.Server{
   171  			config.Server{
   172  				Name:          "FIXME",
   173  				PublicKeyType: "ed25519",
   174  				PublicKey:     rootPublic,
   175  				Addresses: []config.ServerAddress{
   176  					config.ServerAddress{
   177  						Protocol: "udp",
   178  						Address:  "FIXME",
   179  					},
   180  				},
   181  			},
   182  		},
   183  	}
   184  
   185  	jsonBytes, err := json.MarshalIndent(exampleConfig, "", "  ")
   186  	if err != nil {
   187  		return err
   188  	}
   189  
   190  	os.Stdout.Write(jsonBytes)
   191  	os.Stdout.WriteString("\n")
   192  
   193  	return nil
   194  }