Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 1 addition & 59 deletions internal/blockchain/fabric/certs.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,10 @@ package fabric
import (
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/base64"
"encoding/hex"
"encoding/pem"
"fmt"
)

var attributeTypeNames = map[string]string{
"2.5.4.6": "C",
"2.5.4.10": "O",
"2.5.4.11": "OU",
"2.5.4.3": "CN",
"2.5.4.5": "SERIALNUMBER",
"2.5.4.7": "L",
"2.5.4.8": "ST",
"2.5.4.9": "STREET",
"2.5.4.17": "POSTALCODE",
}

func getDNFromCertString(certString string) (string, error) {
cert, err := getCertificateFromBytes(certString)
if err != nil {
Expand All @@ -48,52 +33,9 @@ func getDNFromCertString(certString string) (string, error) {

// borrowed from fabric-chaincode-go to guarantee the same
// resolution of "DN" string from x509 certs
// https://github.com/hyperledger/fabric-chaincode-go/blob/main/pkg/cid/cid.go
func getDN(name *pkix.Name) string {
r := name.ToRDNSequence()
s := ""
for i := 0; i < len(r); i++ {
rdn := r[len(r)-1-i]
if i > 0 {
s += ","
}
for j, tv := range rdn {
if j > 0 {
s += "+"
}
typeString := tv.Type.String()
typeName, ok := attributeTypeNames[typeString]
if !ok {
derBytes, err := asn1.Marshal(tv.Value)
if err == nil {
s += typeString + "=#" + hex.EncodeToString(derBytes)
continue // No value escaping necessary.
}
typeName = typeString
}
valueString := fmt.Sprint(tv.Value)
escaped := ""
begin := 0
for idx, c := range valueString {
if (idx == 0 && (c == ' ' || c == '#')) ||
(idx == len(valueString)-1 && c == ' ') {
escaped += valueString[begin:idx]
escaped += "\\" + string(c)
begin = idx + 1
continue
}
switch c {
case ',', '+', '"', '\\', '<', '>', ';':
escaped += valueString[begin:idx]
escaped += "\\" + string(c)
begin = idx + 1
}
}
escaped += valueString[begin:]
s += typeName + "=" + escaped
}
}
return s
return r.String()
}

func getCertificateFromBytes(certString string) (*x509.Certificate, error) {
Expand Down
84 changes: 84 additions & 0 deletions internal/blockchain/fabric/certs_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright © 2021 Kaleido, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
// 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 fabric

import (
"encoding/base64"
"testing"

"github.com/stretchr/testify/assert"
)

const certWithOutAttrs = `-----BEGIN CERTIFICATE-----
MIICXTCCAgSgAwIBAgIUeLy6uQnq8wwyElU/jCKRYz3tJiQwCgYIKoZIzj0EAwIw
eTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh
biBGcmFuY2lzY28xGTAXBgNVBAoTEEludGVybmV0IFdpZGdldHMxDDAKBgNVBAsT
A1dXVzEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMTcwOTA4MDAxNTAwWhcNMTgw
OTA4MDAxNTAwWjBdMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGggQ2Fyb2xp
bmExFDASBgNVBAoTC0h5cGVybGVkZ2VyMQ8wDQYDVQQLEwZGYWJyaWMxDjAMBgNV
BAMTBWFkbWluMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFq/90YMuH4tWugHa
oyZtt4Mbwgv6CkBSDfYulVO1CVInw1i/k16DocQ/KSDTeTfgJxrX1Ree1tjpaodG
1wWyM6OBhTCBgjAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAdBgNVHQ4E
FgQUhKs/VJ9IWJd+wer6sgsgtZmxZNwwHwYDVR0jBBgwFoAUIUd4i/sLTwYWvpVr
TApzcT8zv/kwIgYDVR0RBBswGYIXQW5pbHMtTWFjQm9vay1Qcm8ubG9jYWwwCgYI
KoZIzj0EAwIDRwAwRAIgCoXaCdU8ZiRKkai0QiXJM/GL5fysLnmG2oZ6XOIdwtsC
IEmCsI8Mhrvx1doTbEOm7kmIrhQwUVDBNXCWX1t3kJVN
-----END CERTIFICATE-----
`
const certWithAttrs = `-----BEGIN CERTIFICATE-----
MIIB6TCCAY+gAwIBAgIUHkmY6fRP0ANTvzaBwKCkMZZPUnUwCgYIKoZIzj0EAwIw
GzEZMBcGA1UEAxMQZmFicmljLWNhLXNlcnZlcjAeFw0xNzA5MDgwMzQyMDBaFw0x
ODA5MDgwMzQyMDBaMB4xHDAaBgNVBAMTE015VGVzdFVzZXJXaXRoQXR0cnMwWTAT
BgcqhkjOPQIBBggqhkjOPQMBBwNCAATmB1r3CdWvOOP3opB3DjJnW3CnN8q1ydiR
dzmuA6A2rXKzPIltHvYbbSqISZJubsy8gVL6GYgYXNdu69RzzFF5o4GtMIGqMA4G
A1UdDwEB/wQEAwICBDAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBTYKLTAvJJK08OM
VGwIhjMQpo2DrjAfBgNVHSMEGDAWgBTEs/52DeLePPx1+65VhgTwu3/2ATAiBgNV
HREEGzAZghdBbmlscy1NYWNCb29rLVByby5sb2NhbDAmBggqAwQFBgcIAQQaeyJh
dHRycyI6eyJhdHRyMSI6InZhbDEifX0wCgYIKoZIzj0EAwIDSAAwRQIhAPuEqWUp
svTTvBqLR5JeQSctJuz3zaqGRqSs2iW+QB3FAiAIP0mGWKcgSGRMMBvaqaLytBYo
9v3hRt1r8j8vN0pMcg==
-----END CERTIFICATE-----
`
const badCert = `-----BEGIN CERTIFICATE-----
MIIB6TCCAY+gAwIBAgIUHkmY6fRP0ANTvzaBwKCkMZZPUnUwCgYIKoZIzj0EAwIw
GzEZMBcGA1UEAxMQZmFicmljLWNhLXNlcnZlcjAeFw0xNzA5MDgwMzQyMDBaFw0x
ODA5MDgwMzQyMDBaMB4xHDAaBgNVBAMTE015VGVzdFVzZXJXaXRoQXR0cnMwWTAT
BgcqhkjOPQIBBggqhkjOPQMBBwNCAATmB1r3CdWvOOP3opB3DjJnW3CnN8q1ydiR
9v3hRt1r8j8vN0pMcg==
-----END CERTIFICATE-----
`

func TestClient(t *testing.T) {
assert := assert.New(t)

certStr := base64.StdEncoding.EncodeToString([]byte(certWithOutAttrs))
cn, err := getDNFromCertString(certStr)
assert.NoError(err, "Error getting ID of the submitter of the transaction")
assert.Equal("CN=admin,OU=Fabric,O=Hyperledger,ST=North Carolina,C=US", cn)

certStr = base64.StdEncoding.EncodeToString([]byte(certWithAttrs))
cn, err = getDNFromCertString(certStr)
assert.NoError(err, "Error getting ID of the submitter of the transaction")
assert.Equal("CN=MyTestUserWithAttrs", cn)

_, err = getDNFromCertString(certWithAttrs)
assert.EqualError(err, "illegal base64 data at input byte 0")

certStr = base64.StdEncoding.EncodeToString([]byte(badCert))
_, err = getDNFromCertString(certStr)
assert.EqualError(err, "asn1: syntax error: data truncated")
}
Loading