forked from CognitionFoundry/gohfc
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathidentity.go
143 lines (125 loc) · 3.45 KB
/
identity.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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
Copyright: Cognition Foundry. All Rights Reserved.
License: Apache License Version 2.0
*/
package gohfc
import (
"crypto/ecdsa"
"crypto/x509"
"encoding/base64"
"encoding/json"
"encoding/pem"
"io/ioutil"
)
// Identity is participant public and private key
type Identity struct {
Certificate *x509.Certificate
PrivateKey interface{}
MspId string
}
// EnrollmentId get enrollment id from certificate
func (i *Identity) EnrollmentId() string {
return i.Certificate.Subject.CommonName
}
// EnrollmentId get enrollment id from certificate
func (i *Identity) ToPem() ([]byte, []byte, error) {
switch i.PrivateKey.(type) {
case *ecdsa.PrivateKey:
cast := i.PrivateKey.(*ecdsa.PrivateKey)
b, err := x509.MarshalECPrivateKey(cast)
if err != nil {
return nil, nil, err
}
privateKey := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: b})
cert := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: i.Certificate.Raw})
return cert, privateKey, nil
default:
return nil, nil, ErrInvalidKeyType
}
}
// MarshalIdentity marshal identity to string
func MarshalIdentity(i *Identity) (string, error) {
var pk, cert string
switch i.PrivateKey.(type) {
case *ecdsa.PrivateKey:
cast := i.PrivateKey.(*ecdsa.PrivateKey)
b, err := x509.MarshalECPrivateKey(cast)
if err != nil {
return "", err
}
block := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: b})
pk = base64.RawStdEncoding.EncodeToString(block)
default:
return "", ErrInvalidKeyType
}
cert = base64.RawStdEncoding.EncodeToString(i.Certificate.Raw)
str, err := json.Marshal(map[string]string{"cert": cert, "pk": pk, "mspid": i.MspId})
if err != nil {
return "", err
}
return string(str), nil
}
// UnmarshalIdentity unmarshal identity from string
func UnmarshalIdentity(data string) (*Identity, error) {
var raw map[string]string
if err := json.Unmarshal([]byte(data), &raw); err != nil {
return nil, err
}
// check do we have all keys
if _, ok := raw["cert"]; !ok || len(raw["cert"]) < 1 {
return nil, ErrInvalidDataForParcelIdentity
}
if _, ok := raw["pk"]; !ok || len(raw["pk"]) < 1 {
return nil, ErrInvalidDataForParcelIdentity
}
certRaw, err := base64.RawStdEncoding.DecodeString(raw["cert"])
if err != nil {
return nil, err
}
cert, err := x509.ParseCertificate(certRaw)
if err != nil {
return nil, err
}
keyRaw, err := base64.RawStdEncoding.DecodeString(raw["pk"])
if err != nil {
return nil, err
}
keyPem, _ := pem.Decode(keyRaw)
if keyPem == nil {
return nil, ErrInvalidDataForParcelIdentity
}
var pk interface{}
switch keyPem.Type {
case "EC PRIVATE KEY":
pk, err = x509.ParseECPrivateKey(keyPem.Bytes)
if err != nil {
return nil, ErrInvalidDataForParcelIdentity
}
default:
return nil, ErrInvalidDataForParcelIdentity
}
identity := &Identity{Certificate: cert, PrivateKey: pk, MspId: raw["mspid"]}
return identity, nil
}
// LoadCertFromFile read public key (pk) and private/secret kye (sk) from file system and return new Identity
func LoadCertFromFile(pk, sk string) (*Identity, error) {
cf, err := ioutil.ReadFile(pk)
if err != nil {
return nil, err
}
kf, err := ioutil.ReadFile(sk)
if err != nil {
return nil, err
}
cpb, _ := pem.Decode(cf)
kpb, _ := pem.Decode(kf)
crt, err := x509.ParseCertificate(cpb.Bytes)
if err != nil {
return nil, err
}
key, err := x509.ParsePKCS8PrivateKey(kpb.Bytes)
if err != nil {
return nil, err
}
return &Identity{Certificate: crt, PrivateKey: key}, nil
}