identity cleanup (#1145)

This commit is contained in:
Bryan White 2019-01-26 15:59:53 +01:00 committed by GitHub
parent 49dacb662c
commit 2b20acbec9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 33 additions and 152 deletions

View File

@ -5,6 +5,7 @@ package main
import (
"fmt"
"os"
"github.com/spf13/cobra"
@ -81,7 +82,7 @@ func init() {
}
func cmdNewCA(cmd *cobra.Command, args []string) error {
_, err := newCACfg.CA.Create(process.Ctx(cmd))
_, err := newCACfg.CA.Create(process.Ctx(cmd), os.Stdout)
return err
}

View File

@ -7,6 +7,7 @@ import (
"crypto/x509/pkix"
"encoding/json"
"fmt"
"os"
"path/filepath"
"github.com/fatih/color"
@ -104,7 +105,7 @@ func cmdNewService(cmd *cobra.Command, args []string) error {
return errs.New("CA certificate and/or key already exits, NOT overwriting!")
}
ca, caerr := caConfig.Create(process.Ctx(cmd))
ca, caerr := caConfig.Create(process.Ctx(cmd), os.Stdout)
if caerr != nil {
return caerr
}

View File

@ -624,7 +624,7 @@ func TestCertificateSigner_Sign_E2E(t *testing.T) {
AuthorizationDBURL: "bolt://" + filepath.Join(tmp, "authorizations.db"),
CA: caConfig,
}
signingCA, err := caSetupConfig.Create(ctx)
signingCA, err := caSetupConfig.Create(ctx, nil)
if !assert.NoError(t, err) {
t.Fatal(err)
}
@ -818,7 +818,7 @@ func TestCertificateSigner_Sign(t *testing.T) {
config := CertServerConfig{
AuthorizationDBURL: "bolt://" + filepath.Join(tmp, "authorizations.db"),
}
signingCA, err := caSetupConfig.Create(ctx)
signingCA, err := caSetupConfig.Create(ctx, nil)
if !assert.NoError(t, err) {
t.Fatal(err)
}

View File

@ -6,7 +6,6 @@ package certificates
import (
"context"
"os"
"time"
"github.com/zeebo/errs"
"go.uber.org/zap"
@ -33,87 +32,6 @@ type CertServerConfig struct {
CA identity.FullCAConfig
}
// SetupIdentity loads or creates a CA and identity and submits a certificate
// signing request request for the CA; if successful, updated chains are saved.
func (c CertClientConfig) SetupIdentity(
ctx context.Context,
caConfig identity.CASetupConfig,
identConfig identity.SetupConfig,
authToken string,
) error {
caStatus := caConfig.Status()
var (
ca *identity.FullCertificateAuthority
ident *identity.FullIdentity
err error
)
switch {
case caStatus == identity.CertKey && !caConfig.Overwrite:
ca, err = caConfig.FullConfig().Load()
if err != nil {
return err
}
case caStatus != identity.NoCertNoKey && !caConfig.Overwrite:
return identity.ErrSetup.New("certificate authority file(s) exist: %s", caStatus)
default:
t, err := time.ParseDuration(caConfig.Timeout)
if err != nil {
return errs.Wrap(err)
}
ctx, cancel := context.WithTimeout(ctx, t)
defer cancel()
ca, err = caConfig.Create(ctx)
if err != nil {
return err
}
}
identStatus := identConfig.Status()
switch {
case identStatus == identity.CertKey && !identConfig.Overwrite:
ident, err = identConfig.FullConfig().Load()
if err != nil {
return err
}
case identStatus != identity.NoCertNoKey && !identConfig.Overwrite:
return identity.ErrSetup.New("identity file(s) exist: %s", identStatus)
default:
ident, err = identConfig.Create(ca)
if err != nil {
return err
}
}
signedChainBytes, err := c.Sign(ctx, ident, authToken)
if err != nil {
return errs.New("error occurred while signing certificate: %s\n(identity files were still generated and saved, if you try again existing files will be loaded)", err)
}
signedChain, err := identity.ParseCertChain(signedChainBytes)
if err != nil {
return nil
}
ca.Cert = signedChain[0]
ca.RestChain = signedChain[1:]
err = identity.FullCAConfig{
CertPath: caConfig.FullConfig().CertPath,
}.Save(ca)
if err != nil {
return err
}
ident.RestChain = signedChain[1:]
err = identity.Config{
CertPath: identConfig.FullConfig().CertPath,
}.Save(ident)
if err != nil {
return err
}
return nil
}
// Sign submits a certificate signing request given the config
func (c CertClientConfig) Sign(ctx context.Context, ident *identity.FullIdentity, authToken string) ([][]byte, error) {
client, err := NewClient(ctx, ident, c.Address)

View File

@ -12,7 +12,9 @@ import (
"crypto/x509"
"encoding/pem"
"fmt"
"io"
"io/ioutil"
"log"
"sync"
"sync/atomic"
@ -67,6 +69,8 @@ type NewCAOptions struct {
ParentCert *x509.Certificate
// ParentKey ()
ParentKey crypto.PrivateKey
// Logger is used to log generation status updates
Logger io.Writer
}
// PeerCAConfig is for locating a CA certificate without a private key
@ -97,16 +101,22 @@ func NewCA(ctx context.Context, opts NewCAOptions) (_ *FullCertificateAuthority,
}
fmt.Printf("Generating key with a minimum a difficulty of %d...\n", opts.Difficulty)
logStatus := func() {
count := atomic.LoadUint32(i)
hs := atomic.LoadUint32(highscore)
fmt.Printf("\rGenerated %d keys; best difficulty so far: %d", count, hs)
updateStatus := func() {
if opts.Logger != nil {
count := atomic.LoadUint32(i)
hs := atomic.LoadUint32(highscore)
_, err := fmt.Fprintf(opts.Logger, "\rGenerated %d keys; best difficulty so far: %d", count, hs)
if err != nil {
log.Print(errs.Wrap(err))
}
}
}
err = GenerateKeys(ctx, minimumLoggableDifficulty, int(opts.Concurrency),
func(k *ecdsa.PrivateKey, id storj.NodeID) (done bool, err error) {
count := atomic.AddUint32(i, 1)
if count%100 == 0 {
logStatus()
if opts.Logger != nil {
if atomic.AddUint32(i, 1)%100 == 0 {
updateStatus()
}
}
difficulty, err := id.Difficulty()
@ -116,12 +126,17 @@ func NewCA(ctx context.Context, opts NewCAOptions) (_ *FullCertificateAuthority,
if difficulty >= opts.Difficulty {
mu.Lock()
if selectedKey == nil {
logStatus()
updateStatus()
selectedKey = k
selectedID = id
}
mu.Unlock()
fmt.Printf("\nFound a key with difficulty %d!\n", difficulty)
if opts.Logger != nil {
_, err := fmt.Fprintf(opts.Logger, "\nFound a key with difficulty %d!\n", difficulty)
if err != nil {
log.Print(errs.Wrap(err))
}
}
return true, nil
}
for {
@ -130,7 +145,7 @@ func NewCA(ctx context.Context, opts NewCAOptions) (_ *FullCertificateAuthority,
return false, nil
}
if atomic.CompareAndSwapUint32(highscore, hs, uint32(difficulty)) {
logStatus()
updateStatus()
return false, nil
}
}
@ -164,7 +179,7 @@ func (caS CASetupConfig) Status() TLSFilesStatus {
}
// Create generates and saves a CA using the config
func (caS CASetupConfig) Create(ctx context.Context) (*FullCertificateAuthority, error) {
func (caS CASetupConfig) Create(ctx context.Context, logger io.Writer) (*FullCertificateAuthority, error) {
var (
err error
parent *FullCertificateAuthority
@ -188,6 +203,7 @@ func (caS CASetupConfig) Create(ctx context.Context) (*FullCertificateAuthority,
Concurrency: caS.Concurrency,
ParentCert: parent.Cert,
ParentKey: parent.Key,
Logger: logger,
})
if err != nil {
return nil, err

View File

@ -4,9 +4,6 @@
package identity
import (
"context"
"time"
"github.com/zeebo/errs"
)
@ -14,51 +11,3 @@ var (
// ErrSetup is returned when there's an error with setup
ErrSetup = errs.Class("setup error")
)
// SetupIdentity ensures a CA and identity exist
func SetupIdentity(ctx context.Context, c CASetupConfig, i SetupConfig) error {
if s := c.Status(); s != NoCertNoKey && !c.Overwrite {
return ErrSetup.New("certificate authority file(s) exist: %s", s)
}
var cancel func()
if c.Timeout != "0" {
t, err := time.ParseDuration(c.Timeout)
if err != nil {
return errs.Wrap(err)
}
ctx, cancel = context.WithTimeout(ctx, t)
defer cancel()
}
// Create a new certificate authority
ca, err := c.Create(ctx)
if err != nil {
return err
}
if s := i.Status(); s != NoCertNoKey && !i.Overwrite {
return ErrSetup.New("identity file(s) exist: %s", s)
}
// Create identity from new CA
_, err = i.Create(ca)
return err
}
// SetupCA ensures a CA exists
func SetupCA(ctx context.Context, c CASetupConfig) error {
if s := c.Status(); s != NoCertNoKey && !c.Overwrite {
return ErrSetup.New("certificate authority file(s) exist: %s", s)
}
t, err := time.ParseDuration(c.Timeout)
if err != nil {
return errs.Wrap(err)
}
ctx, cancel := context.WithTimeout(ctx, t)
defer cancel()
// Create a new certificate authority
_, err = c.Create(ctx)
return err
}

View File

@ -42,10 +42,6 @@ var (
PeerIdentityFromContext = identity.PeerIdentityFromContext
// NewFullIdentity Transition: pkg/provider is going away.
NewFullIdentity = identity.NewFullIdentity
// SetupIdentity Transition: pkg/provider is going away.
SetupIdentity = identity.SetupIdentity
// SetupCA Transition: pkg/provider is going away.
SetupCA = identity.SetupCA
// NewCA Transition: pkg/provider is going away.
NewCA = identity.NewCA
// ErrSetup Transition: pkg/provider is going away.