forked from holochain/holochain-proto
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathagent.go
119 lines (104 loc) · 2.31 KB
/
agent.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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Copyright (C) 2013-2017, The MetaCurrency Project (Eric Harris-Braun, Arthur Brock, et. al.)
// Use of this source code is governed by GPLv3 found in the LICENSE file
//---------------------------------------------------------------------------------------
// key generation and marshal/unmarshaling for holochains
package holochain
import (
"crypto/rand"
"errors"
"fmt"
ic "github.com/libp2p/go-libp2p-crypto"
)
// Unique user identifier in context of this holochain
type AgentID string
type KeytypeType int
const (
IPFS = iota
)
type Agent interface {
ID() AgentID
KeyType() KeytypeType
GenKeys() error
PrivKey() ic.PrivKey
PubKey() ic.PubKey
}
type IPFSAgent struct {
Id AgentID
Priv ic.PrivKey
}
func (a *IPFSAgent) ID() AgentID {
return a.Id
}
func (a *IPFSAgent) KeyType() KeytypeType {
return IPFS
}
func (a *IPFSAgent) PrivKey() ic.PrivKey {
return a.Priv
}
func (a *IPFSAgent) PubKey() ic.PubKey {
return a.Priv.GetPublic()
}
func (a *IPFSAgent) GenKeys() (err error) {
var priv ic.PrivKey
priv, _, err = ic.GenerateEd25519Key(rand.Reader)
if err != nil {
return
}
a.Priv = priv
return
}
// NewAgent creates an agent structure of the given type
// Note: currently only IPFS agents are implemented
func NewAgent(keyType KeytypeType, id AgentID) (agent Agent, err error) {
switch keyType {
case IPFS:
a := IPFSAgent{
Id: id,
}
err = a.GenKeys()
if err != nil {
return
}
agent = &a
default:
err = fmt.Errorf("unknown key type: %d", keyType)
}
return
}
// SaveAgent saves out the keys and agent id to the given directory
func SaveAgent(path string, agent Agent) (err error) {
writeFile(path, AgentFileName, []byte(agent.ID()))
if err != nil {
return
}
if fileExists(path + "/" + PrivKeyFileName) {
return errors.New("keys already exist")
}
var k []byte
k, err = agent.PrivKey().Bytes()
if err != nil {
return
}
err = writeFile(path, PrivKeyFileName, k)
return
}
// LoadAgent gets the agent and signing key from the specified directory
func LoadAgent(path string) (agent Agent, err error) {
id, err := readFile(path, AgentFileName)
if err != nil {
return
}
a := IPFSAgent{
Id: AgentID(id),
}
k, err := readFile(path, PrivKeyFileName)
if err != nil {
return nil, err
}
a.Priv, err = ic.UnmarshalPrivateKey(k)
if err != nil {
return
}
agent = &a
return
}