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
func main() {
	app := cli.NewApp()
	app.Name = "gen-ct-bundle"
	app.Version = fmt.Sprintf("0.1.0 [%s]", core.GetBuildID())

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "config",
			Value:  "config.json",
			EnvVar: "BOULDER_CONFIG",
			Usage:  "Path to Boulder JSON configuration file",
		},
		cli.StringSliceFlag{
			Name:  "cert",
			Value: &cli.StringSlice{},
			Usage: "Paths to PEM certificates in order from issuer -> root",
		},
		cli.StringFlag{
			Name:  "out",
			Usage: "Path to write out the DER certificate bundle",
		},
	}

	app.Action = func(c *cli.Context) {
		bundleFilename := c.GlobalString("out")
		if bundleFilename == "" {
			fmt.Fprintf(os.Stderr, "-out flag is required\n")
			os.Exit(1)
		}
		fmt.Println(bundleFilename)

		configFileName := c.GlobalString("config")
		configJSON, err := ioutil.ReadFile(configFileName)
		cmd.FailOnError(err, "Unable to read config file")

		var config cmd.Config
		err = json.Unmarshal(configJSON, &config)
		cmd.FailOnError(err, "Failed to read configuration")

		if config.Publisher.CT == nil {
			fmt.Fprintf(os.Stderr, "Publisher CT configuration required to assemble correct root pool\n")
			os.Exit(1)
		}

		certFilenames := c.GlobalStringSlice("cert")
		if len(certFilenames) == 0 {
			//
		}
		var chain []*x509.Certificate
		for _, certFilename := range certFilenames {
			cert, err := core.LoadCert(certFilename)
			cmd.FailOnError(err, fmt.Sprintf("Failed to load certificate (%s)", certFilename))
			chain = append(chain, cert)
		}

		roots := x509.NewCertPool()
		roots.AddCert(chain[len(chain)-1])
		opts := x509.VerifyOptions{Roots: roots}

		if len(chain) > 2 {
			inters := x509.NewCertPool()
			for _, inter := range chain[1 : len(chain)-1] {
				inters.AddCert(inter)
			}
			opts.Intermediates = inters
		}
		_, err = chain[0].Verify(opts)
		cmd.FailOnError(err, "Failed to load chain")

		client := http.Client{}
		maxLen := 0
		for _, ctLog := range config.Publisher.CT.Logs {
			fmt.Printf("# %s\n", ctLog.URI)
			logRoots, err := downloadCTRootList(&client, ctLog.URI)
			cmd.FailOnError(err, "Failed to retrieve root certificates")
			ctPool := x509.NewCertPool()
			for _, root := range logRoots {
				ctPool.AddCert(root)
			}
			ctOpts := x509.VerifyOptions{Roots: ctPool}
			var lastValidChain []*x509.Certificate
			fmt.Println("\tTesting chain validity with downloaded log root pool")
			for i := range chain {
				if len(chain)-i > 1 {
					ctOpts.Intermediates = x509.NewCertPool()
					for _, inter := range chain[1 : len(chain)-i] {
						ctOpts.Intermediates.AddCert(inter)
					}
				} else {
					ctOpts.Intermediates = nil
				}
				fmt.Printf("\t\t%s -> constructed root pool", prettyChain(chain[:len(chain)-i]))
				if _, err := chain[0].Verify(ctOpts); err != nil {
					fmt.Println(": Invalid!")
					break
				}
				fmt.Println(": Valid!")
				lastValidChain = chain[:len(chain)-i]
			}
			if len(lastValidChain) == 0 {
				fmt.Println("\n\t!! Couldn't construct any valid chains, this may mean you haven't   !!")
				fmt.Println("\t!! provided the full chain or that this CT log doesn't contain a    !!")
				fmt.Println("\t!! root certificates that chain those provided. In the case of the  !!")
				fmt.Println("\t!! latter you should remove this log from your configuration since  !!")
				fmt.Println("\t!! your submissions will fail and be discarded.                     !!")
				continue
			}
			fmt.Printf("\n\tBundle size for %s: %d\n", ctLog.URI, len(lastValidChain))
			if len(lastValidChain) > maxLen {
				maxLen = len(lastValidChain)
			}
		}

		if maxLen == 0 {
			fmt.Println("\n!! Couldn't find any valid chains for configured logs, this may     !!")
			fmt.Println("!! mean you haven't provided the full chain or that this CT log     !!")
			fmt.Println("!! doesn't contain a root certificates that chain those provided.   !!")
			fmt.Println("!! The bundle will still be written out but you should only use     !!")
			fmt.Println("!! this if you really know what you are doing!                      !!")
			maxLen = len(chain)
		}
		fmt.Printf("\n# Shared bundle size: %d certificates, %s\n", maxLen, prettyChain(chain[:maxLen]))

		// Write bundle out
		f, err := os.Create(bundleFilename)
		cmd.FailOnError(err, fmt.Sprintf("Failed to create submission bundle (%s)", bundleFilename))
		defer f.Close()

		for _, cert := range chain[:maxLen] {
			f.Write(cert.Raw)
		}
		fmt.Printf("# CT submission bundle has been written to %s\n", bundleFilename)
	}

	err := app.Run(os.Args)
	cmd.FailOnError(err, "Failed to run application")
}
Example #5
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))
		}
	}
}