Example #1
0
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
	}

}
Example #2
0
// 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()
		}
	}
}
Example #3
0
// 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
}
Example #4
0
// 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))
		}
	}
}