func VerifyDerCert(der_cert []byte, der_signing_cert []byte) (bool, error) { roots := x509.NewCertPool() opts := x509.VerifyOptions{ Roots: roots, } // Verify key policy_cert, err := x509.ParseCertificate(der_signing_cert) if err != nil { return false, errors.New("Signing ParseCertificate fails") } roots.AddCert(policy_cert) fmt.Printf("Root cert: %x\n", der_signing_cert) // Verify key cert, err := x509.ParseCertificate(der_cert) if err != nil { return false, errors.New("Cert ParseCertificate fails") } roots.AddCert(policy_cert) opts.Roots = roots chains, err := cert.Verify(opts) if err != nil { return false, errors.New("Verify fails") } if chains != nil { return true, nil } else { return false, nil } }
// Validates incoming connection client certificates, // and identifies the node they are associated with, // then sends the new connection to that node to handle. func acceptIncoming(ch <-chan *tls.Conn) { for { conn := <-ch state := conn.ConnectionState() if len(state.PeerCertificates) == 0 { conn.Close() continue } cert := state.PeerCertificates[0] // Find the node this connection is from. matched := false for _, node := range logic.Nodes { if node == logic.Me { continue } var verifyOpts x509.VerifyOptions verifyOpts.Intermediates = new(x509.CertPool) verifyOpts.Roots = node.Cert chains, err := cert.Verify(verifyOpts) if err != nil { continue } if len(chains) > 0 { matched = true node.NewConn <- conn break } } // No matching node found. Close the connection. if !matched { conn.Close() } } }
// AuthenticatePrincipal runs a synchronous protocol to authenticate a single // principal on a single channel. In this toy implementation, it is assumed that // there are no other principals on the channel and that there are no other // simultaneous channels. func (m *ResourceMaster) AuthenticatePrincipal(ms util.MessageStream, msg *Message, programPolicy *ProgramPolicy) ([]byte, error) { // The certificate message is passed in by the caller as the first // message. // Process the certificate. For AUTH_CERT, the data is just the // certificate. cert, err := x509.ParseCertificate([]byte(msg.Data)) if err != nil { log.Printf("couldn't Parse Certificate in AuthenticatePrincipal\n") return nil, err } // Set up a nonce challenge for the reply. For NONCE_CHALL, the data is // also just the message itself. reply := &Message{ Type: MessageType_NONCE_CHALL.Enum(), Data: make([]byte, NonceSize), } if _, err = rand.Read(reply.Data); err != nil { return nil, err } // Step 1: Send a nonce to the principal. if _, err := ms.WriteMessage(reply); err != nil { return nil, err } // Step 2: Wait for the signed response. var s Message if err := ms.ReadMessage(&s); err != nil { return nil, err } if *s.Type != MessageType_SIGNED_NONCE { return nil, fmt.Errorf("received message was not SIGNED_NONCE") } // Verify the certificate against the root. // TODO(tmroeder): move the VerifyOptions up into the ResourceMaster. var opts x509.VerifyOptions roots := x509.NewCertPool() policyCert, err := x509.ParseCertificate(programPolicy.PolicyCert) if err != nil || policyCert == nil { return nil, err } roots.AddCert(policyCert) opts.Roots = roots chains, err := cert.Verify(opts) if chains == nil || err != nil { return nil, err } v, err := tao.FromX509(cert) if err != nil { return nil, err } ok, err := v.Verify(reply.Data, ChallengeContext, s.Data) if err != nil { return nil, err } if err := sendResult(ms, ok); err != nil { return nil, fmt.Errorf("failed to return a result to the client") } if !ok { return nil, fmt.Errorf("the nonce signature did not pass verification") } return msg.Data, nil }
// Blocks listening for connections of that given protocol type, // and calls the specified handler when one is received, // passing the node ID of the connecting node, or 0 for the Client Protocol. func Listen(protocol int, handler func(id uint16, b *BaseConn)) { ip := config.NodeIP(config.Id()) ipStr := ip.String() port := getProtocolPort(protocol) portStr := strconv.FormatInt(int64(port), 10) tlsConfig := new(tls.Config) tlsConfig.Certificates = []tls.Certificate{*config.Certificate()} if protocol != CLIENT_PROTOCOL { tlsConfig.ClientAuth = tls.RequireAnyClientCert } listener, err := tls.Listen("tcp", ipStr+":"+portStr, tlsConfig) if err != nil { log.Fatal(err) } for { conn, err := listener.Accept() if err != nil { log.Fatal(err) } tlsConn := conn.(*tls.Conn) err = tlsConn.Handshake() if err != nil { tlsConn.Close() continue } if protocol != CLIENT_PROTOCOL { // Check this connecting node has authenticated. state := tlsConn.ConnectionState() if len(state.PeerCertificates) == 0 { tlsConn.Close() continue } cert := state.PeerCertificates[0] // Identify which node they authenticated as. matched := false for _, node := range config.Nodes() { var verifyOpts x509.VerifyOptions verifyOpts.Intermediates = new(x509.CertPool) verifyOpts.Roots = config.NodeCertPool(node) chains, err := cert.Verify(verifyOpts) if err != nil { continue } // Matched the node. Start the handler. if len(chains) > 0 { matched = true go handler(node, newBaseConn(tlsConn)) break } } // No matching node found. Close the connection. if !matched { tlsConn.Close() } } else { // We don't authenticate clients. // Just run the handler. handler(0, newBaseConn(tlsConn)) } } }