storj/pkg/provider/utils.go

166 lines
2.8 KiB
Go
Raw Normal View History

Node Identity (#193) * peertls: don't log errors for double close understood that this part of the code is undergoing heavy change right now, but just want to make sure this fix gets incorporated somewhere * git cleanup: node-id stuff * cleanup * rename identity_util.go * wip `CertificateAuthority` refactor * refactoring * gitignore update * wip * Merge remote-tracking branch 'storj/doubleclose' into node-id3 * storj/doubleclose: peertls: don't log errors for double close * add peertls tests & gomports * wip: + refactor + style changes + cleanup + [wip] add version to CA and identity configs + [wip] heavy client setup * refactor * wip: + refactor + style changes + add `CAConfig.Load` + add `CAConfig.Save` * wip: + add `LoadOrCreate` and `Create` to CA and Identity configs + add overwrite to CA and identity configs + heavy client setup + refactor + style changes + cleanup * wip * fixing things * fixing things * wip hc setup * hc setup: + refactor + bugfixing * improvements based on reveiw feedback * goimports * improvements: + responding to review feedback + refactor * feedback-based improvements * feedback-based improvements * feedback-based improvements * feedback-based improvements * feedback-based improvements * feedback-based improvements * cleanup * refactoring CA and Identity structs * Merge branch 'master' into node-id3 * move version field to setup config structs for CA and identity * fix typo * responding to revieiw feedback * responding to revieiw feedback * responding to revieiw feedback * responding to revieiw feedback * responding to revieiw feedback * responding to revieiw feedback * Merge branch 'master' into node-id3 * fix gateway setup finally * go imports * fix `FullCertificateAuthority.GenerateIdentity` * cleanup overlay tests * bugfixing * update ca/identity setup * go imports * fix peertls test copy/paste fail * responding to review feedback * setup tweaking * update farmer setup
2018-08-13 09:39:45 +01:00
// Copyright (C) 2018 Storj Labs, Inc.
// See LICENSE for copying information.
package provider
import (
"context"
"crypto"
"crypto/ecdsa"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"os"
"path/filepath"
"github.com/zeebo/errs"
"golang.org/x/crypto/sha3"
"storj.io/storj/pkg/peertls"
)
type TlsFilesStat int
const (
NoCertNoKey = iota
CertNoKey
NoCertKey
CertKey
)
var (
ErrZeroBytes = errs.New("byte slice was unexpectedly empty")
)
func decodePEM(PEMBytes []byte) ([][]byte, error) {
DERBytes := [][]byte{}
for {
var DERBlock *pem.Block
DERBlock, PEMBytes = pem.Decode(PEMBytes)
if DERBlock == nil {
break
}
DERBytes = append(DERBytes, DERBlock.Bytes)
}
if len(DERBytes) == 0 || len(DERBytes[0]) == 0 {
return nil, ErrZeroBytes
}
return DERBytes, nil
}
func generateCAWorker(ctx context.Context, difficulty uint16, caC chan FullCertificateAuthority, eC chan error) {
var (
k crypto.PrivateKey
i nodeID
err error
)
for {
select {
case <-ctx.Done():
return
default:
k, err = peertls.NewKey()
switch kE := k.(type) {
case *ecdsa.PrivateKey:
i, err = idFromKey(&kE.PublicKey)
if err != nil {
eC <- err
return
}
default:
eC <- peertls.ErrUnsupportedKey.New("%T", k)
return
}
}
if i.Difficulty() >= difficulty {
break
}
}
ct, err := peertls.CATemplate()
if err != nil {
eC <- err
return
}
c, err := peertls.NewCert(ct, nil, k)
if err != nil {
eC <- err
return
}
ca := FullCertificateAuthority{
Cert: c,
Key: k,
ID: i,
}
caC <- ca
return
}
func idFromKey(k crypto.PublicKey) (nodeID, error) {
kb, err := x509.MarshalPKIXPublicKey(k)
if err != nil {
return "", errs.Wrap(err)
}
hash := make([]byte, IdentityLength)
sha3.ShakeSum256(hash, kb)
return nodeID(base64.URLEncoding.EncodeToString(hash)), nil
}
func openCert(path string, flag int) (*os.File, error) {
if err := os.MkdirAll(filepath.Dir(path), 744); err != nil {
return nil, errs.Wrap(err)
}
c, err := os.OpenFile(path, flag, 0644)
if err != nil {
return nil, errs.New("unable to open cert file for writing \"%s\"", path, err)
}
return c, nil
}
func openKey(path string, flag int) (*os.File, error) {
if err := os.MkdirAll(filepath.Dir(path), 700); err != nil {
return nil, errs.Wrap(err)
}
k, err := os.OpenFile(path, flag, 0600)
if err != nil {
return nil, errs.New("unable to open key file for writing \"%s\"", path, err)
}
return k, nil
}
func statTLSFiles(certPath, keyPath string) TlsFilesStat {
s := 0
_, err := os.Stat(certPath)
if err == nil {
s += 1
}
_, err = os.Stat(keyPath)
if err == nil {
s += 2
}
return TlsFilesStat(s)
}
func (t TlsFilesStat) String() string {
switch t {
case CertKey:
return "certificate and key"
case CertNoKey:
return "certificate"
case NoCertKey:
return "key"
default:
return ""
}
}