github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/support_infrastructure/SimpleDomainService/simpledomainservice.go (about)

     1  // Copyright (c) 2014, 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  //     http://www.apache.org/licenses/LICENSE-2.0
     7  // Unless required by applicable law or agreed to in writing, software
     8  // distributed under the License is distributed on an "AS IS" BASIS,
     9  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    10  // See the License for the specific language governing permissions and
    11  // limitations under the License.
    12  
    13  package main
    14  
    15  import (
    16  	"bytes"
    17  	"crypto/tls"
    18  	"crypto/x509"
    19  	"crypto/x509/pkix"
    20  	"errors"
    21  	"flag"
    22  	"log"
    23  	"math/big"
    24  	"net"
    25  	"time"
    26  
    27  	"github.com/golang/protobuf/proto"
    28  	"github.com/jlmucb/cloudproxy/go/support_libraries/domain_policy"
    29  	"github.com/jlmucb/cloudproxy/go/tao"
    30  	"github.com/jlmucb/cloudproxy/go/tao/auth"
    31  	"github.com/jlmucb/cloudproxy/go/util"
    32  )
    33  
    34  var network = flag.String("network", "tcp", "The network to use for connections")
    35  var addr = flag.String("addr", "localhost:8124", "The address to listen on")
    36  var domainPass = flag.String("password", "xxx", "The domain password")
    37  var configPath = flag.String("config",
    38  	"/Domains/domain.simpleexample/tao.config", "The Tao domain config")
    39  var servicePath = flag.String("service_path",
    40  	"/Domains/domain.simpleexample/SimpleDomainService", "The Tao domain config")
    41  
    42  var SerialNumber int64
    43  
    44  func IsAuthenticationValid(name *string) bool {
    45  	log.Printf("simpledomainservice, IsAuthenticationValid name is %s\n", *name)
    46  	if name == nil {
    47  		return false
    48  	}
    49  	log.Printf("simpledomainservice, IsAuthenticationValid returning true\n")
    50  	return true
    51  }
    52  
    53  
    54  // First return is terminate flag.
    55  func DomainRequest(conn net.Conn, policyKey *tao.Keys, guard tao.Guard) (bool, error) {
    56  	log.Printf("DomainRequest\n")
    57  
    58  	// Expect a request with attestation from client.
    59  	ms := util.NewMessageStream(conn)
    60  	var request domain_policy.DomainCertRequest
    61  	err := ms.ReadMessage(&request)
    62  	if err != nil {
    63  		log.Printf("DomainRequest: Couldn't read attestation from channel. Error : %v", err)
    64  		log.Printf("\n")
    65  		return false, err
    66  	}
    67  
    68  	var a tao.Attestation
    69  	err = proto.Unmarshal(request.Attestation, &a)
    70  	if request.KeyType == nil {
    71  		log.Printf("Domain: Empty key type")
    72  		return false, errors.New("Empty key type")
    73  	}
    74  
    75  log.Printf("SimpleDomainService: got attestation and request ")
    76  	switch *request.KeyType {
    77  	case "ecdsap256-public", "ecdsap384-public", "ecdsap521-public",
    78  		"ecdsap256", "ecdsap384", "ecdsap521":
    79  		break
    80  	default:
    81  		log.Printf("Domain: bad key type")
    82  		return false, errors.New("Domain: bad key type")
    83  	}
    84  
    85  	subjectVerifier, err := tao.VerifierKeyFromCanonicalKeyBytes(request.SubjectPublicKey)
    86  	if err != nil {
    87  		log.Printf("DomainRequest: can't get key from der")
    88  		return false, errors.New("DomainRequest: can't get key from der")
    89  	}
    90  	subjectKeyHash, err := subjectVerifier.UniversalKeyNameFromVerifier()
    91  	if err != nil {
    92  		log.Printf("SimpleDomain DomainRequest: calculate universal name")
    93  		return false, errors.New("SimpleDomain DomainRequest: can't get key from der")
    94  	}
    95  	peerCert := conn.(*tls.Conn).ConnectionState().PeerCertificates[0]
    96  	log.Printf("\n")
    97  	log.Printf("\nNumber of peer certs: %d\n", len(conn.(*tls.Conn).ConnectionState().PeerCertificates))
    98  	for i := 0; i < len(conn.(*tls.Conn).ConnectionState().PeerCertificates); i++ {
    99  		tao.PrintPKIXName("Issuer", &conn.(*tls.Conn).ConnectionState().PeerCertificates[i].Issuer)
   100  		tao.PrintPKIXName("Subject", &conn.(*tls.Conn).ConnectionState().PeerCertificates[i].Subject)
   101  		log.Printf("\n")
   102  	}
   103  	// TODO(jlm): Change this.
   104  	err = tao.ValidatePeerAttestation(&a, peerCert, guard)
   105  	/*
   106  	   if err != nil {
   107  	       log.Printf("Domain: RequestCouldn't validate peer attestation:", err)
   108  	   		 return false, err
   109  	   }
   110  	   fmt.Printf("DomainRequest, peerCert: %x\n", peerCert)
   111  	*/
   112  
   113  	// Sign cert
   114  log.Printf("SimpleDomainService: signing cert")
   115  
   116  	// Get Program name and key info from delegation.
   117  	f, err := auth.UnmarshalForm(a.SerializedStatement)
   118  	if err != nil {
   119  		log.Printf("DomainRequest: Can't unmarshal a.SerializedStatement\n")
   120  		return false, err
   121  	}
   122  
   123  	var saysStatement *auth.Says
   124  	if ptr, ok := f.(*auth.Says); ok {
   125  		saysStatement = ptr
   126  	} else if val, ok := f.(auth.Says); ok {
   127  		saysStatement = &val
   128  	}
   129  	sf, ok := saysStatement.Message.(auth.Speaksfor)
   130  	if ok != true {
   131  		log.Printf("DomainRequest: says doesnt have speaksfor message\n")
   132  		return false, err
   133  	}
   134  	// this in the new key principal
   135  	clientKeyPrincipal, ok := sf.Delegate.(auth.Prin)
   136  	if ok != true {
   137  		log.Printf("DomainRequest: speaksfor Delegate is not auth.Prin\n")
   138  		return false, err
   139  	}
   140  
   141  	programPrincipal, ok := sf.Delegator.(auth.Prin)
   142  	if ok != true {
   143  		log.Printf("DomainRequest: Can't get subject principal\n")
   144  		return false, errors.New("Can't get principal name from verifier")
   145  	}
   146  	programPrincipalName := programPrincipal.String()
   147  	verified := IsAuthenticationValid(&programPrincipalName)
   148  	if !verified {
   149  		log.Printf("DomainRequest: name verification failed\n")
   150  		return false, err
   151  	}
   152  	log.Printf("SimpleDomainService: key principal: %s, program principal: %s\n", clientKeyPrincipal, programPrincipalName)
   153  
   154  	// Is the delegate the same key as was presented in the name in the request?
   155  	namedHash := clientKeyPrincipal.KeyHash.(auth.Bytes)
   156  	log.Printf("keyhash: %x\n", namedHash)
   157  	if bytes.Compare(subjectKeyHash[:], namedHash) != 0 {
   158  		log.Printf("DomainRequest: named hash is wrong, named: %x, computed: %x\n",
   159  			namedHash, subjectKeyHash)
   160  		return false, errors.New("DomainRequest: named hash is wrong")
   161  	}
   162  
   163  	// Sign program certificate.
   164  
   165  	notBefore := time.Now()
   166  	validFor := 365 * 24 * time.Hour
   167  	notAfter := notBefore.Add(validFor)
   168  
   169  	us := "US"
   170  	localhost := "localhost"
   171  	x509SubjectName := &pkix.Name{
   172  		Organization:       []string{programPrincipalName},
   173  		OrganizationalUnit: []string{programPrincipalName},
   174  		CommonName:         localhost,
   175  		Country:            []string{us},
   176  	}
   177  
   178  	log.Printf("Signing cert for ")
   179  	tao.PrintPKIXName("Subject", x509SubjectName)
   180  	log.Printf(" with \n")
   181  	tao.PrintPKIXName("Issuer", &policyKey.Cert.Issuer)
   182  	log.Printf("\n")
   183  
   184  	SerialNumber = SerialNumber + 1
   185  	var sn big.Int
   186  	certificateTemplate := &x509.Certificate{
   187  		SerialNumber: &sn,
   188  		Issuer:    policyKey.Cert.Issuer,
   189  		Subject:   *x509SubjectName,
   190  		NotBefore: notBefore,
   191  		NotAfter:  notAfter,
   192  		KeyUsage:  x509.KeyUsageCertSign | x509.KeyUsageKeyAgreement | x509.KeyUsageDigitalSignature,
   193  	}
   194  
   195  	signerAlg := tao.SignerTypeFromSuiteName(tao.TaoCryptoSuite)
   196  	if signerAlg == nil {
   197  		return false, errors.New("Bad suite")
   198  	}
   199  	pkAlg := tao.PublicKeyAlgFromSignerAlg(*signerAlg)
   200  	sigAlg := tao.SignatureAlgFromSignerAlg(*signerAlg)
   201  	if pkAlg < 0 || sigAlg < 0 {
   202  		return false, errors.New("Bad signing algs")
   203  	}
   204  	clientCert, err := policyKey.SigningKey.CreateSignedX509FromTemplate(policyKey.Cert, certificateTemplate,
   205  		subjectVerifier, pkAlg, sigAlg)
   206  
   207  	zero := int32(0)
   208  	var ra domain_policy.DomainCertResponse
   209  	ra.Error = &zero
   210  	ra.SignedCert = clientCert.Raw
   211  
   212  	// Add cert chain (just policy cert for now).
   213  	ra.CertChain = append(ra.CertChain, policyKey.Cert.Raw)
   214  
   215  	_, err = ms.WriteMessage(&ra)
   216  	if err != nil {
   217  		log.Printf("DomainRequest: Couldn't return the attestation on the channel. Error: %v", err)
   218  		log.Printf("\n")
   219  		return false, err
   220  	}
   221  	return false, nil
   222  }
   223  
   224  func main() {
   225  	flag.Parse()
   226  	domain, err := tao.LoadDomain(*configPath, []byte(*domainPass))
   227  	if domain == nil {
   228  		log.Printf("simpledomainservice: no domain path - %s, pass - %s, err - %s\n",
   229  			*configPath, *domainPass, err)
   230  		return
   231  	} else if err != nil {
   232  		log.Printf("simpledomainservice: Couldn't load the config path %s: %s\n",
   233  			*configPath, err)
   234  		return
   235  	}
   236  	log.Printf("simpledomainservice: Loaded domain\n")
   237  	if domain.Keys.Cert == nil {
   238  		log.Printf("\nPolicy key Cert is nil\n")
   239  	} else {
   240  		log.Printf("\nPolicy Cert Issuer: \n")
   241  		tao.PrintPKIXName("Issuer", &domain.Keys.Cert.Issuer)
   242  		log.Printf("\nPolicy Cert Subject: \n")
   243  		tao.PrintPKIXName("Subject", &domain.Keys.Cert.Subject)
   244  		log.Printf("\n\n")
   245  	}
   246  	log.Printf("\n")
   247  
   248  	// Set up temporary keys for the connection, since the only thing that
   249  	// matters to the remote client is that they receive a correctly-signed new
   250  	// attestation from the policy key.
   251  	// JLM:  I left this in place but I'm not sure what a TLS connection with a
   252  	//   self signed Cert buys in terms of security.
   253  	//   The security of this protocol should not depend on the
   254  	//   confidentiality or intergity of the channel.  All that said, if we
   255  	//   do ever distribute a signed simpledomainservice cert
   256  	// for this TLS channel, it would be good.
   257  	keys, err := tao.NewTemporaryKeys(tao.Signing)
   258  	if keys == nil || err != nil {
   259  		log.Fatalln("simpledomainservice: Couldn't set up temporary keys for connection:", err)
   260  		return
   261  	}
   262  	pkAlg := tao.PublicKeyAlgFromSignerAlg(*keys.SigningKey.Header.KeyType)
   263  	sigAlg := tao.SignatureAlgFromSignerAlg(*keys.SigningKey.Header.KeyType)
   264  	keys.Cert, err = keys.SigningKey.CreateSelfSignedX509(pkAlg, sigAlg, int64(1),
   265  		&pkix.Name{
   266  			Organization: []string{"Google Tao Demo"}})
   267  	if err != nil {
   268  		log.Fatalln("simpledomainservice: Couldn't set up a self-signed cert:", err)
   269  		return
   270  	}
   271  	SerialNumber = int64(time.Now().UnixNano()) / (1000000)
   272  	policyKey := domain.Keys
   273  	log.Printf("SimpleDomainService: policyKey: %v\n", policyKey)
   274  	log.Printf("SimpleDomainService: policyKey Subject: ")
   275  	tao.PrintPKIXName("Subject", &policyKey.Cert.Subject)
   276  	log.Printf("\n")
   277  
   278  	tlsc, err := tao.EncodeTLSCert(keys)
   279  	if err != nil {
   280  		log.Fatalln("simpledomainservice: Couldn't encode a TLS cert:", err)
   281  	}
   282  	conf := &tls.Config{
   283  		RootCAs:            x509.NewCertPool(),
   284  		Certificates:       []tls.Certificate{*tlsc},
   285  		InsecureSkipVerify: true,
   286  		ClientAuth:         tls.RequireAnyClientCert,
   287  	}
   288  	sock, err := tls.Listen(*network, *addr, conf)
   289  	if err != nil {
   290  		log.Printf("simpledomainservice: error: %s\n", err)
   291  	}
   292  	if sock == nil {
   293  		log.Printf("simpledomainservice: Empty socket, terminating\n")
   294  		return
   295  	}
   296  	defer sock.Close()
   297  
   298  	log.Printf("simpledomainservice: accepting connections\n")
   299  	for {
   300  		conn, err := sock.Accept()
   301  		if conn == nil {
   302  			log.Printf("simpledomainservice: Empty connection\n")
   303  			return
   304  		} else if err != nil {
   305  			log.Printf("simpledomainservice: Couldn't accept a connection on %s: %s\n", *addr, err)
   306  			return
   307  		}
   308  		go DomainRequest(conn, policyKey, domain.Guard)
   309  	}
   310  	log.Println("simpledomainservice: finishing")
   311  }