Skip to content

Commit b86a86f

Browse files
yacovmGerrit Code Review
authored and
Gerrit Code Review
committed
Merge "[FAB-17095] Pretty print peer identities in gossip"
2 parents f30f3f0 + 0cd1107 commit b86a86f

File tree

3 files changed

+124
-0
lines changed

3 files changed

+124
-0
lines changed

gossip/api/crypto.go

+43
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,16 @@ SPDX-License-Identifier: Apache-2.0
77
package api
88

99
import (
10+
"crypto/x509"
11+
"encoding/base64"
12+
"encoding/json"
13+
"encoding/pem"
14+
"fmt"
1015
"time"
1116

17+
"github.com/golang/protobuf/proto"
1218
cb "github.com/hyperledger/fabric-protos-go/common"
19+
"github.com/hyperledger/fabric-protos-go/msp"
1320
"github.com/hyperledger/fabric/gossip/common"
1421
"google.golang.org/grpc"
1522
)
@@ -108,6 +115,42 @@ func (pis PeerIdentitySet) Filter(filter PeerIdentityFilter) PeerIdentitySet {
108115
// PeerIdentityType is the peer's certificate
109116
type PeerIdentityType []byte
110117

118+
// String returns a string representation of this PeerIdentityType
119+
func (pit PeerIdentityType) String() string {
120+
base64Representation := base64.StdEncoding.EncodeToString(pit)
121+
sID := &msp.SerializedIdentity{}
122+
err := proto.Unmarshal(pit, sID)
123+
if err != nil {
124+
return fmt.Sprintf("non SerializedIdentity: %s", base64Representation)
125+
}
126+
127+
bl, _ := pem.Decode(sID.IdBytes)
128+
if bl == nil {
129+
return fmt.Sprintf("non PEM encoded identity: %s", base64Representation)
130+
}
131+
132+
cert, _ := x509.ParseCertificate(bl.Bytes)
133+
if cert == nil {
134+
return fmt.Sprintf("non x509 identity: %s", base64Representation)
135+
}
136+
m := make(map[string]interface{})
137+
m["MSP"] = sID.Mspid
138+
s := cert.Subject
139+
m["CN"] = s.CommonName
140+
m["OU"] = s.OrganizationalUnit
141+
m["L-ST-C"] = fmt.Sprintf("%s-%s-%s", s.Locality, s.StreetAddress, s.Country)
142+
i := cert.Issuer
143+
m["Issuer-CN"] = i.CommonName
144+
m["Issuer-OU"] = i.OrganizationalUnit
145+
m["Issuer-L-ST-C"] = fmt.Sprintf("%s-%s-%s", i.Locality, i.StreetAddress, i.Country)
146+
147+
rawJSON, err := json.Marshal(m)
148+
if err != nil {
149+
return base64Representation
150+
}
151+
return string(rawJSON)
152+
}
153+
111154
// PeerSuspector returns whether a peer with a given identity is suspected
112155
// as being revoked, or its CA is revoked
113156
type PeerSuspector func(identity PeerIdentityType) bool

gossip/api/crypto_test.go

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package api
8+
9+
import (
10+
"encoding/pem"
11+
"io/ioutil"
12+
"path/filepath"
13+
"testing"
14+
15+
"github.com/hyperledger/fabric-protos-go/msp"
16+
"github.com/hyperledger/fabric/protoutil"
17+
"github.com/stretchr/testify/assert"
18+
)
19+
20+
func TestPeerIdentityTypeString(t *testing.T) {
21+
certBytes, err := ioutil.ReadFile(filepath.Join("testdata", "peer.pem"))
22+
assert.NoError(t, err)
23+
24+
for _, testCase := range []struct {
25+
description string
26+
identity PeerIdentityType
27+
expectedOut string
28+
}{
29+
{
30+
description: "non serialized identity",
31+
identity: PeerIdentityType("some garbage"),
32+
expectedOut: "non SerializedIdentity: c29tZSBnYXJiYWdl",
33+
},
34+
{
35+
description: "non PEM identity",
36+
identity: PeerIdentityType(protoutil.MarshalOrPanic(&msp.SerializedIdentity{
37+
Mspid: "SampleOrg",
38+
IdBytes: []byte{1, 2, 3},
39+
})),
40+
expectedOut: "non PEM encoded identity: CglTYW1wbGVPcmcSAwECAw==",
41+
},
42+
{
43+
description: "non x509 identity",
44+
identity: PeerIdentityType(protoutil.MarshalOrPanic(&msp.SerializedIdentity{
45+
Mspid: "SampleOrg",
46+
IdBytes: pem.EncodeToMemory(&pem.Block{
47+
Type: "CERTIFICATE",
48+
Bytes: []byte{1, 2, 3},
49+
}),
50+
})),
51+
expectedOut: `non x509 identity: CglTYW1wbGVPcmcSOy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpBUUlECi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K`,
52+
},
53+
{
54+
description: "x509 identity",
55+
identity: PeerIdentityType(protoutil.MarshalOrPanic(&msp.SerializedIdentity{
56+
Mspid: "SampleOrg",
57+
IdBytes: certBytes,
58+
})),
59+
expectedOut: `{"CN":"peer0.org1.example.com","Issuer-CN":"ca.org1.example.com","Issuer-L-ST-C":"[San Francisco]-[]-[US]","Issuer-OU":["COP"],"L-ST-C":"[San Francisco]-[]-[US]","MSP":"SampleOrg","OU":["COP"]}`,
60+
},
61+
} {
62+
t.Run(testCase.description, func(t *testing.T) {
63+
assert.Equal(t, testCase.identity.String(), testCase.expectedOut)
64+
})
65+
}
66+
67+
}

gossip/api/testdata/peer.pem

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIICNjCCAd2gAwIBAgIRAMnf9/dmV9RvCCVw9pZQUfUwCgYIKoZIzj0EAwIwgYEx
3+
CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4g
4+
RnJhbmNpc2NvMRkwFwYDVQQKExBvcmcxLmV4YW1wbGUuY29tMQwwCgYDVQQLEwND
5+
T1AxHDAaBgNVBAMTE2NhLm9yZzEuZXhhbXBsZS5jb20wHhcNMTcxMTEyMTM0MTEx
6+
WhcNMjcxMTEwMTM0MTExWjBpMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZv
7+
cm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEMMAoGA1UECxMDQ09QMR8wHQYD
8+
VQQDExZwZWVyMC5vcmcxLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D
9+
AQcDQgAEZ8S4V71OBJpyMIVZdwYdFXAckItrpvSrCf0HQg40WW9XSoOOO76I+Umf
10+
EkmTlIJXP7/AyRRSRU38oI8Ivtu4M6NNMEswDgYDVR0PAQH/BAQDAgeAMAwGA1Ud
11+
EwEB/wQCMAAwKwYDVR0jBCQwIoAginORIhnPEFZUhXm6eWBkm7K7Zc8R4/z7LW4H
12+
ossDlCswCgYIKoZIzj0EAwIDRwAwRAIgVikIUZzgfuFsGLQHWJUVJCU7pDaETkaz
13+
PzFgsCiLxUACICgzJYlW7nvZxP7b6tbeu3t8mrhMXQs956mD4+BoKuNI
14+
-----END CERTIFICATE-----

0 commit comments

Comments
 (0)