Skip to content

Commit f951497

Browse files
committed
add multiple callsign domain support
1 parent e7233cf commit f951497

9 files changed

Lines changed: 233 additions & 186 deletions

File tree

api/adscert.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ message RequestInfo {
1111
bytes url_hash = 2;
1212
bytes body_hash = 3;
1313
repeated SignatureInfo signature_info = 4;
14+
// useful if 1 signatory is managing multiple origin domains such as in resellers case.
15+
string origin_domain = 5;
1416
}
1517

1618
// SignatureInfo captures the signature generated for the signing request. It

cmd/server/main.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,6 @@ func main() {
2828
logger.SetLevel(parsedLogLevel)
2929
logger.Infof("Log Level: %s, parsed as iota %v", *logLevel, parsedLogLevel)
3030

31-
if *origin == "" {
32-
logger.Fatalf("Origin ads.cert Call Sign domain name is required")
33-
}
34-
3531
if *privateKey == "" {
3632
logger.Fatalf("Private key is required")
3733
}

examples/signer-client/signer-client.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616

1717
var (
1818
serverAddress = flag.String("server_address", "localhost:3000", "address of grpc server")
19+
originDomain = flag.String("origin_domain", "", "Origin domain")
1920
destinationURL = flag.String("url", "https://google.com/gen_204", "URL to invoke")
2021
body = flag.String("body", "", "POST request body")
2122
signingTimeout = flag.Duration("signing_timeout", 5*time.Millisecond, "Specifies how long this client will wait for signing to finish before abandoning.")
@@ -49,6 +50,9 @@ func main() {
4950
// destination URL and body, setting these value on the RequestInfo message.
5051
reqInfo := &api.RequestInfo{}
5152
signatory.SetRequestInfo(reqInfo, *destinationURL, []byte(*body))
53+
if originDomain != nil {
54+
reqInfo.OriginDomain = *originDomain
55+
}
5256

5357
// Request the signature.
5458
logger.Infof("signing request for url: %v", *destinationURL)

internal/formats/adscert_connection_signature.go

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,22 +132,21 @@ func EncodeSignatureSuffix(
132132
}
133133

134134
func NewAuthenticatedConnectionSignature(status AuthenticatedConnectionProtocolStatus, from string, invoking string) (*AuthenticatedConnectionSignature, error) {
135+
s := &AuthenticatedConnectionSignature{}
136+
s.status = status
137+
s.from = from
138+
s.invoking = invoking
135139

136140
if status == StatusUnspecified {
137-
return nil, ErrParamMissingStatus
141+
return s, ErrParamMissingStatus
138142
}
139143
if from == "" {
140-
return nil, ErrParamMissingFrom
144+
return s, ErrParamMissingFrom
141145
}
142146
if invoking == "" {
143-
return nil, ErrParamMissingInvoking
147+
return s, ErrParamMissingInvoking
144148
}
145149

146-
s := &AuthenticatedConnectionSignature{}
147-
s.status = status
148-
s.from = from
149-
s.invoking = invoking
150-
151150
return s, nil
152151
}
153152

pkg/adscert/api/adscert.pb.go

Lines changed: 158 additions & 147 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/adscert/api/adscert_grpc.pb.go

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/adscert/discovery/domain_indexer_impl.go

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ func NewDefaultDomainIndexer(dnsResolver DNSResolver, domainStore DomainStore, d
3131
domainRenewalInterval: domainRenewalInterval,
3232
dnsResolver: dnsResolver,
3333
domainStore: domainStore,
34+
currentPrivateKey: make(map[string]keyAlias),
3435
}
3536

3637
myPrivateKeys, err := privateKeysToKeyMap(base64PrivateKeys)
@@ -39,12 +40,14 @@ func NewDefaultDomainIndexer(dnsResolver DNSResolver, domainStore DomainStore, d
3940
}
4041
di.myPrivateKeys = myPrivateKeys
4142

42-
for _, privateKey := range di.myPrivateKeys {
43-
// since iterating over a map is non-deterministic, we can make sure to set the key
44-
// either if it is not already set or it is alphabetically less than current key at the index when
45-
// iterating over the private keys map.
46-
if di.currentPrivateKey == "" || di.currentPrivateKey < privateKey.alias {
47-
di.currentPrivateKey = privateKey.alias
43+
for originCallsign := range di.myPrivateKeys {
44+
for _, privateKey := range di.myPrivateKeys[originCallsign] {
45+
// since iterating over a map is non-deterministic, we can make sure to set the key
46+
// either if it is not already set or it is alphabetically less than current key at the index when
47+
// iterating over the private keys map.
48+
if di.currentPrivateKey[originCallsign] == "" || di.currentPrivateKey[originCallsign] < privateKey.alias {
49+
di.currentPrivateKey[originCallsign] = privateKey.alias
50+
}
4851
}
4952
}
5053

@@ -62,8 +65,8 @@ type defaultDomainIndexer struct {
6265
lastRun time.Time
6366
lastRunLock sync.RWMutex
6467

65-
myPrivateKeys keyMap
66-
currentPrivateKey keyAlias
68+
myPrivateKeys map[string]keyMap
69+
currentPrivateKey map[string]keyAlias
6770

6871
dnsResolver DNSResolver
6972
domainStore DomainStore
@@ -227,21 +230,27 @@ func (di *defaultDomainIndexer) checkDomainForKeyRecords(ctx context.Context, cu
227230
}
228231

229232
// create shared secrets for each private key + public key combination
230-
for _, myKey := range di.myPrivateKeys {
231-
for _, theirKey := range currentDomainInfo.allPublicKeys {
232-
keyPairAlias := newKeyPairAlias(myKey.alias, theirKey.alias)
233-
if currentDomainInfo.allSharedSecrets[keyPairAlias] == nil {
234-
currentDomainInfo.allSharedSecrets[keyPairAlias], err = calculateSharedSecret(myKey, theirKey)
235-
if err != nil {
236-
logger.Warningf("error calculating shared secret for record %s: %v", currentDomainInfo.Domain, err)
237-
currentDomainInfo.domainStatus = DomainStatusErrorOnSharedSecretCalculation
233+
for originCallsign := range di.myPrivateKeys {
234+
if originCallsign != currentDomainInfo.Domain {
235+
continue
236+
}
237+
238+
for _, myKey := range di.myPrivateKeys[originCallsign] {
239+
for _, theirKey := range currentDomainInfo.allPublicKeys {
240+
keyPairAlias := newKeyPairAlias(myKey.alias, theirKey.alias)
241+
if currentDomainInfo.allSharedSecrets[keyPairAlias] == nil {
242+
currentDomainInfo.allSharedSecrets[keyPairAlias], err = calculateSharedSecret(myKey, theirKey)
243+
if err != nil {
244+
logger.Warningf("error calculating shared secret for record %s: %v", currentDomainInfo.Domain, err)
245+
currentDomainInfo.domainStatus = DomainStatusErrorOnSharedSecretCalculation
246+
}
238247
}
239248
}
240249
}
241-
}
242250

243-
currentDomainInfo.currentSharedSecretId = newKeyPairAlias(di.currentPrivateKey, currentDomainInfo.currentPublicKeyId)
244-
currentDomainInfo.lastUpdateTime = time.Now()
251+
currentDomainInfo.currentSharedSecretId = newKeyPairAlias(di.currentPrivateKey[originCallsign], currentDomainInfo.currentPublicKeyId)
252+
currentDomainInfo.lastUpdateTime = time.Now()
253+
}
245254
}
246255

247256
func parsePolicyRecords(baseSubdomain string, baseSubdomainRecords []string) (foundDomains []string, parseError bool) {

pkg/adscert/discovery/internal_base_key.go

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package discovery
22

33
import (
4+
"errors"
45
"fmt"
6+
"strings"
57

68
"github.com/IABTechLab/adscert/internal/formats"
79
"github.com/IABTechLab/adscert/pkg/adscert/logger"
@@ -76,11 +78,14 @@ func calculateSharedSecret(originPrivateKey *x25519Key, remotePublicKey *x25519K
7678
return result, err
7779
}
7880

79-
func privateKeysToKeyMap(privateKeys []string) (keyMap, error) {
80-
result := keyMap{}
81-
81+
func privateKeysToKeyMap(privateKeys []string) (map[string]keyMap, error) {
82+
results := map[string]keyMap{}
8283
for _, privateKeyBase64 := range privateKeys {
83-
privateKey, err := parseKeyFromString(privateKeyBase64)
84+
sp := strings.SplitN(privateKeyBase64, "|", 2)
85+
if len(sp) < 2 {
86+
return nil, errors.New("missing origin callsign")
87+
}
88+
privateKey, err := parseKeyFromString(sp[1])
8489
if err != nil {
8590
return nil, err
8691
}
@@ -90,10 +95,16 @@ func privateKeysToKeyMap(privateKeys []string) (keyMap, error) {
9095

9196
keyAlias := keyAlias(formats.ExtractKeyAliasFromPublicKeyBase64(formats.EncodeKeyBase64(publicBytes[:])))
9297
privateKey.alias = keyAlias
93-
result[keyAlias] = privateKey
98+
99+
km := results[sp[0]]
100+
if km == nil {
101+
km = keyMap{}
102+
}
103+
km[keyAlias] = privateKey
104+
results[sp[0]] = km
94105
}
95106

96-
return result, nil
107+
return results, nil
97108
}
98109

99110
func parseKeyFromString(base64EncodedKey string) (*x25519Key, error) {

pkg/adscert/signatory/signatory_local_impl.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ func NewLocalAuthenticatedConnectionsSignatory(
2828
domainRenewalInterval time.Duration,
2929
base64PrivateKeys []string) *LocalAuthenticatedConnectionsSignatory {
3030
logger.SetLevel(logger.GetLevelFromString(logLevel))
31+
if originCallsign != "" {
32+
for i := range base64PrivateKeys {
33+
base64PrivateKeys[i] = originCallsign + "|" + base64PrivateKeys[i]
34+
}
35+
}
3136
return &LocalAuthenticatedConnectionsSignatory{
3237
originCallsign: originCallsign,
3338
secureRandom: secureRandom,
@@ -93,9 +98,15 @@ func (s *LocalAuthenticatedConnectionsSignatory) SignAuthenticatedConnection(req
9398
}
9499

95100
func (s *LocalAuthenticatedConnectionsSignatory) signSingleMessage(request *api.AuthenticatedConnectionSignatureRequest, domainInfo discovery.DomainInfo) (*api.SignatureInfo, error) {
96-
97101
sigInfo := &api.SignatureInfo{}
98-
acs, err := formats.NewAuthenticatedConnectionSignature(formats.StatusOK, s.originCallsign, request.RequestInfo.InvokingDomain)
102+
103+
var originCallsign string
104+
if request.RequestInfo.OriginDomain != "" {
105+
originCallsign = request.RequestInfo.OriginDomain
106+
} else {
107+
originCallsign = s.originCallsign
108+
}
109+
acs, err := formats.NewAuthenticatedConnectionSignature(formats.StatusOK, originCallsign, request.RequestInfo.InvokingDomain)
99110
if err != nil {
100111
acs.SetStatus(formats.StatusErrorOnSignature)
101112
setSignatureInfoFromAuthenticatedConnection(sigInfo, acs)

0 commit comments

Comments
 (0)