mirror of
https://github.com/mudler/edgevpn.git
synced 2025-09-26 21:01:44 +08:00

As EdgeVPN can be used as library and it turns out to be quite useful, change license for follow up versions to Apache so can be used as a library easilier.
100 lines
3.6 KiB
Go
100 lines
3.6 KiB
Go
/*
|
|
Copyright © 2021-2022 Ettore Di Giacinto <mudler@mocaccino.org>
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package ecdsa
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/ipfs/go-log/v2"
|
|
"github.com/mudler/edgevpn/pkg/blockchain"
|
|
"github.com/mudler/edgevpn/pkg/hub"
|
|
"github.com/mudler/edgevpn/pkg/node"
|
|
)
|
|
|
|
type ECDSA521 struct {
|
|
privkey string
|
|
logger log.StandardLogger
|
|
}
|
|
|
|
// ECDSA521Provider returns an ECDSA521 auth provider.
|
|
// To use it, use the following configuration to provide a
|
|
// private key: AuthProviders: map[string]map[string]interface{}{"ecdsa": {"private_key": "<key>"}},
|
|
// While running, keys can be added from a TZ node also from the api, for example:
|
|
// curl -X PUT 'http://localhost:8081/api/ledger/trustzoneAuth/ecdsa_1/<key>'
|
|
// Note: privkey and pubkeys are in the format generated by GenerateKeys() down below
|
|
// The provider resolves "ecdsa" keys in the trustzone auth area, and
|
|
// uses each one as pubkey to try to auth against
|
|
func ECDSA521Provider(ll log.StandardLogger, privkey string) (*ECDSA521, error) {
|
|
return &ECDSA521{privkey: privkey, logger: ll}, nil
|
|
}
|
|
|
|
// Authenticate a message against a set of pubkeys.
|
|
// It cycles over all the Trusted zone Auth data ( providers options, not where senders ID are stored)
|
|
// and detects any key with ecdsa prefix. Values are assumed to be string and parsed as pubkeys.
|
|
// The pubkeys are then used to authenticate nodes and verify if any of the pubkeys validates the challenge.
|
|
func (e *ECDSA521) Authenticate(m *hub.Message, c chan *hub.Message, tzdata map[string]blockchain.Data) bool {
|
|
|
|
sigs, ok := m.Annotations["sigs"]
|
|
if !ok {
|
|
e.logger.Debug("No signature in message", m.Message, m.Annotations)
|
|
|
|
return false
|
|
}
|
|
|
|
e.logger.Debug("ECDSA auth Received", m)
|
|
|
|
pubKeys := []string{}
|
|
for k, t := range tzdata {
|
|
if strings.Contains(k, "ecdsa") {
|
|
var s string
|
|
t.Unmarshal(&s)
|
|
pubKeys = append(pubKeys, s)
|
|
}
|
|
}
|
|
if len(pubKeys) == 0 {
|
|
e.logger.Debug("ECDSA auth: No pubkeys to auth against")
|
|
// no pubkeys to authenticate present in the ledger
|
|
return false
|
|
}
|
|
for _, pubkey := range pubKeys {
|
|
// Try verifying the signature
|
|
if err := verify([]byte(pubkey), []byte(fmt.Sprint(sigs)), bytes.NewBufferString(m.Message)); err == nil {
|
|
e.logger.Debug("ECDSA auth: Signature verified")
|
|
return true
|
|
}
|
|
e.logger.Debug("ECDSA auth: Signature not verified")
|
|
}
|
|
return false
|
|
}
|
|
|
|
// Challenger sends ECDSA521 challenges over the public channel if the current node is not in the trusted zone.
|
|
// This start a challenge which eventually should get the node into the TZ
|
|
func (e *ECDSA521) Challenger(inTrustZone bool, c node.Config, n *node.Node, b *blockchain.Ledger, trustData map[string]blockchain.Data) {
|
|
if !inTrustZone {
|
|
e.logger.Debug("ECDSA auth: current node not in trustzone, sending challanges")
|
|
signature, err := sign([]byte(e.privkey), bytes.NewBufferString("challenge"))
|
|
if err != nil {
|
|
e.logger.Error("Error signing message: ", err.Error())
|
|
return
|
|
}
|
|
msg := hub.NewMessage("challenge")
|
|
msg.Annotations = make(map[string]interface{})
|
|
msg.Annotations["sigs"] = string(signature)
|
|
n.PublishMessage(msg)
|
|
return
|
|
}
|
|
}
|