forked from lyriarte/blockchain-ssm
-
Notifications
You must be signed in to change notification settings - Fork 4
/
agent.go
99 lines (83 loc) · 2.1 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
// Copyright Luc Yriarte <luc.yriarte@thingagora.org> 2018
// License: Apache-2.0
package main
import (
"errors"
"crypto"
"crypto/x509"
"crypto/sha256"
"crypto/rsa"
"encoding/json"
"encoding/pem"
"encoding/base64"
"github.com/hyperledger/fabric/core/chaincode/shim"
)
type Agent struct {
AgentModel
}
//
// Storable interface implementation
//
func (self *Agent) Put(stub shim.ChaincodeStubInterface, key string) error {
data, err := self.Serialize()
if (err != nil) {
return err
}
return stub.PutState(key, data)
}
func (self *Agent) Get(stub shim.ChaincodeStubInterface, key string) error {
data, err := stub.GetState(key);
if (err != nil) {
return err
}
return self.Deserialize(data)
}
//
// Serializable interface implementation
//
func (self *Agent) Serialize() ([]byte, error) {
return json.Marshal(self.AgentModel)
}
func (self *Agent) Deserialize(data []byte) error {
return json.Unmarshal(data, &self.AgentModel)
}
//
// Agent API implementation
//
func (self *Agent) PublicKey() (crypto.PublicKey, error) {
// PEM from base 64
pemStr := "-----BEGIN PUBLIC KEY-----\n"
var i int
for i = 0; i < len(self.AgentModel.Pub)-64; i += 64 {
pemStr += self.AgentModel.Pub[i:i+64] + "\n"
}
pemStr += self.AgentModel.Pub[i:len(self.AgentModel.Pub)] + "\n"
pemStr += "-----END PUBLIC KEY-----\n"
// Public Key from PEM
block, _ := pem.Decode([]byte(pemStr))
if block == nil {
return nil, errors.New("Invalid agent PEM block")
}
if block.Type != "PUBLIC KEY" {
return nil, errors.New("Agent PEM block is not a public key")
}
return x509.ParsePKIXPublicKey(block.Bytes)
}
func (self *Agent) Verify(message string, b64sign string) error {
// Retrieve agent's public key
pubKey, err := self.PublicKey()
if err != nil {
return err
}
// Explicit cast to RSA public key
pubKeyRSA := pubKey.(*rsa.PublicKey)
// Decode base 64 signature
signature, err := base64.StdEncoding.DecodeString(b64sign)
if err != nil {
return err
}
// Calculate message hash
hash := sha256.Sum256([]byte(message))
// Verify signature
return rsa.VerifyPKCS1v15(pubKeyRSA, crypto.SHA256, hash[:], signature)
}