123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- /*
- Copyright © 2021-2022 Ettore Di Giacinto <[email protected]>
- 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
- }
- }
|