예제 #1
0
파일: client.go 프로젝트: denkhaus/lecert
func New(cnf *config.Config) (*Client, error) {
	lcli, err := letsencrypt.NewClient(cnf.AcmeURL)
	if err != nil {
		return nil, errors.Annotate(err, "new le client")
	}

	os.MkdirAll(cnf.OutputDir, 0700)
	accountKey, err := getAccountKey(lcli, cnf.KeyFile, cnf.Bits)
	if err != nil {
		return nil, errors.Annotate(err, "get account key")
	}

	var resp ChallengeResponder
	if cnf.ModeStandalone {
		log.Debug("create http challenge responder")
		h, err := NewHTTPChallengeResponder(cnf.BindAddress)
		if err != nil {
			return nil, errors.Annotate(err, "new http challenge responder")
		}
		resp = h
	}
	if cnf.ModeWebRoot {
		log.Debug("create webroot challenge responder")
		h, err := NewWebRootChallengeResponder(cnf.RootPath)
		if err != nil {
			return nil, errors.Annotate(err, "new webroot challenge responder")
		}
		resp = h
	}

	if resp == nil {
		return nil, errors.New("challenge responder undefined")
	}

	return &Client{Client: lcli, accountKey: accountKey, ChallengeResponder: resp}, nil
}
예제 #2
0
파일: letsencrypt.go 프로젝트: jtolds/lecat
func requestServerCert(serverKey *rsa.PrivateKey) (*x509.Certificate, error) {
	accountKey, err := loadKey("account")
	if err != nil {
		return nil, err
	}

	cli, err := letsencrypt.NewClient(*apiServer)
	if err != nil {
		return nil, err
	}

	log.Printf("(re)registering account key")
	_, err = cli.NewRegistration(accountKey)
	if err != nil {
		return nil, err
	}

	log.Printf("getting challenges for %#v", *reachableHost)
	// ask for a set of challenges for a given domain
	auth, _, err := cli.NewAuthorization(accountKey, "dns", *reachableHost)
	if err != nil {
		return nil, err
	}

	chals := auth.Combinations(letsencrypt.ChallengeTLSSNI)
	if len(chals) != 1 && len(chals[0]) != 1 {
		return nil, fmt.Errorf("no supported challenge combinations")
	}

	log.Printf("performing sni challenge")
	chal := chals[0][0]
	if chal.Type != letsencrypt.ChallengeTLSSNI {
		return nil, fmt.Errorf("not a tls sni challenge")
	}

	certs, err := chal.TLSSNI(accountKey)
	if err != nil {
		return nil, err
	}

	getCertificate := func(clientHello *tls.ClientHelloInfo) (
		*tls.Certificate, error) {
		if cert, ok := certs[clientHello.ServerName]; ok {
			return cert, nil
		}
		return nil, nil
	}

	selfSigned, err := selfSignedCert(serverKey)
	if err != nil {
		return nil, err
	}

	config := &tls.Config{
		Certificates: []tls.Certificate{{
			Certificate: [][]byte{selfSigned.Raw},
			PrivateKey:  serverKey,
			Leaf:        selfSigned}},
		NextProtos:     []string{"http/1.1"},
		GetCertificate: getCertificate}

	l, err := tls.Listen("tcp", *listenAddr, config)
	if err != nil {
		return nil, err
	}
	defer l.Close()

	var wg sync.WaitGroup
	wg.Add(1)

	go func() {
		defer wg.Done()
		(&http.Server{Handler: http.HandlerFunc(http.NotFound)}).Serve(l)
	}()

	log.Printf("waiting for challenge")
	err = cli.ChallengeReady(accountKey, chal)
	if err != nil {
		return nil, err
	}

	log.Printf("making csr")
	csr, err := newCSR(serverKey)
	if err != nil {
		return nil, err
	}

	log.Printf("getting cert")
	res, err := cli.NewCertificate(accountKey, csr)
	if err != nil {
		return nil, err
	}

	l.Close()
	wg.Wait()

	return res.Certificate, nil
}