-
Notifications
You must be signed in to change notification settings - Fork 17
/
tls.go
88 lines (71 loc) · 2.18 KB
/
tls.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// Copyright (C) 2021 Storj Labs, Inc.
// See LICENSE for copying information.
package uplink
import (
"context"
"sync"
"sync/atomic"
"storj.io/common/identity"
"storj.io/common/peertls/tlsopts"
)
var processTLSOptions struct {
mu sync.Mutex
tlsOptions atomic.Pointer[tlsopts.Options]
}
var processTLSOptionsByPEM sync.Map
func getProcessTLSOptionsFromPEM(chainPEM, keyPEM []byte) (*tlsopts.Options, error) {
if len(chainPEM) == 0 || len(keyPEM) == 0 {
return nil, packageError.New("both chain and key PEM must be provided")
}
lookupKey := [2]*byte{&chainPEM[0], &keyPEM[0]}
// first check the memoized value as a fast path with no locks
tlsOptionsI, ok := processTLSOptionsByPEM.Load(lookupKey)
if ok {
return tlsOptionsI.(*tlsopts.Options), nil
}
// it was a miss so create an identity from the pem data and make the tls options
ident, err := identity.FullIdentityFromPEM(chainPEM, keyPEM)
if err != nil {
return nil, packageError.Wrap(err)
}
tlsOptions, err := tlsOptionsFromIdentity(ident)
if err != nil {
return nil, packageError.Wrap(err)
}
tlsOptionsI, _ = processTLSOptionsByPEM.LoadOrStore(lookupKey, tlsOptions)
return tlsOptionsI.(*tlsopts.Options), nil
}
func getProcessTLSOptions(ctx context.Context) (*tlsopts.Options, error) {
if tlsOptions := processTLSOptions.tlsOptions.Load(); tlsOptions != nil {
return tlsOptions, nil
}
processTLSOptions.mu.Lock()
defer processTLSOptions.mu.Unlock()
if tlsOptions := processTLSOptions.tlsOptions.Load(); tlsOptions != nil {
return tlsOptions, nil
}
ident, err := identity.NewFullIdentity(ctx, identity.NewCAOptions{
Difficulty: 0,
Concurrency: 1,
})
if err != nil {
return nil, packageError.Wrap(err)
}
tlsOptions, err := tlsOptionsFromIdentity(ident)
if err != nil {
return nil, packageError.Wrap(err)
}
processTLSOptions.tlsOptions.Store(tlsOptions)
return tlsOptions, nil
}
func tlsOptionsFromIdentity(ident *identity.FullIdentity) (*tlsopts.Options, error) {
tlsConfig := tlsopts.Config{
UsePeerCAWhitelist: false,
PeerIDVersions: "0",
}
tlsOptions, err := tlsopts.NewOptions(ident, tlsConfig, nil)
if err != nil {
return nil, packageError.Wrap(err)
}
return tlsOptions, nil
}