Skip to content

Commit

Permalink
[FAB-5350] Compute MSP-ID afert cert sanitisation
Browse files Browse the repository at this point in the history
This change-set does the following:
- It enforces that the MSP Identity Identifier,
whose value depends on the identity's certificate,
is computed after certificate sanitisation.
This way, we are sure that the ID is unique.

Tests have been added.

Change-Id: I67090be70625a9d0c3bd18a78fd8e16db89b0dae
Signed-off-by: Angelo De Caro <adc@zurich.ibm.com>
  • Loading branch information
adecaro committed Jul 28, 2017
1 parent 3e4ae31 commit 5a65700
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 52 deletions.
26 changes: 22 additions & 4 deletions msp/identities.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,32 @@ type identity struct {
msp *bccspmsp
}

func newIdentity(id *IdentityIdentifier, cert *x509.Certificate, pk bccsp.Key, msp *bccspmsp) (Identity, error) {
mspIdentityLogger.Debugf("Creating identity instance for ID %s", id)
func newIdentity(cert *x509.Certificate, pk bccsp.Key, msp *bccspmsp) (Identity, error) {
mspIdentityLogger.Debugf("Creating identity instance for cert %s", cert)

// Sanitize first the certificate
cert, err := msp.sanitizeCert(cert)
if err != nil {
return nil, err
}

// Compute identity identifier

// Use the hash of the identity's certificate as id in the IdentityIdentifier
hashOpt, err := bccsp.GetHashOpt(msp.cryptoConfig.IdentityIdentifierHashFunction)
if err != nil {
return nil, fmt.Errorf("Failed getting hash function options [%s]", err)
}

digest, err := msp.bccsp.Hash(cert.Raw, hashOpt)
if err != nil {
return nil, fmt.Errorf("Failed hashing raw certificate to compute the id of the IdentityIdentifier [%s]", err)
}

id := &IdentityIdentifier{
Mspid: msp.name,
Id: hex.EncodeToString(digest)}

return &identity{id: id, cert: cert, pk: pk, msp: msp}, nil
}

Expand Down Expand Up @@ -188,9 +206,9 @@ type signingidentity struct {
signer crypto.Signer
}

func newSigningIdentity(id *IdentityIdentifier, cert *x509.Certificate, pk bccsp.Key, signer crypto.Signer, msp *bccspmsp) (SigningIdentity, error) {
func newSigningIdentity(cert *x509.Certificate, pk bccsp.Key, signer crypto.Signer, msp *bccspmsp) (SigningIdentity, error) {
//mspIdentityLogger.Infof("Creating signing identity instance for ID %s", id)
mspId, err := newIdentity(id, cert, pk, msp)
mspId, err := newIdentity(cert, pk, msp)
if err != nil {
return nil, err
}
Expand Down
61 changes: 61 additions & 0 deletions msp/msp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ limitations under the License.
package msp

import (
"crypto/ecdsa"
"crypto/x509"
"encoding/hex"
"encoding/pem"
"errors"
"fmt"
"os"
Expand Down Expand Up @@ -933,3 +937,60 @@ func getLocalMSP(t *testing.T, dir string) MSP {

return thisMSP
}

func TestMSPIdentityIdentifier(t *testing.T) {
// testdata/mspid
// 1) a key and a signcert (used to populate the default signing identity) with the cert having a HighS signature
thisMSP := getLocalMSP(t, "testdata/mspid")

id, err := thisMSP.GetDefaultSigningIdentity()
assert.NoError(t, err)
err = id.Validate()
assert.NoError(t, err)

// Check that the identity identifier is computed with the respect to the lowS signature

idid := id.GetIdentifier()
assert.NotNil(t, idid)

// Load and parse cacaert and signcert from folder
pems, err := getPemMaterialFromDir("testdata/mspid/cacerts")
assert.NoError(t, err)
bl, _ := pem.Decode(pems[0])
assert.NotNil(t, bl)
caCertFromFile, err := x509.ParseCertificate(bl.Bytes)
assert.NoError(t, err)

pems, err = getPemMaterialFromDir("testdata/mspid/signcerts")
assert.NoError(t, err)
bl, _ = pem.Decode(pems[0])
assert.NotNil(t, bl)
certFromFile, err := x509.ParseCertificate(bl.Bytes)
assert.NoError(t, err)
// Check that the certificates' raws are different, meaning that the identity has been sanitised
assert.NotEqual(t, certFromFile.Raw, id.(*signingidentity).cert)

// Check that certFromFile is in HighS
_, S, err := sw.UnmarshalECDSASignature(certFromFile.Signature)
assert.NoError(t, err)
lowS, err := sw.IsLowS(caCertFromFile.PublicKey.(*ecdsa.PublicKey), S)
assert.NoError(t, err)
assert.False(t, lowS)

// Check that id.(*signingidentity).cert is in LoswS
_, S, err = sw.UnmarshalECDSASignature(id.(*signingidentity).cert.Signature)
assert.NoError(t, err)
lowS, err = sw.IsLowS(caCertFromFile.PublicKey.(*ecdsa.PublicKey), S)
assert.NoError(t, err)
assert.True(t, lowS)

// Compute the digest for certFromFile
thisBCCSPMsp := thisMSP.(*bccspmsp)
hashOpt, err := bccsp.GetHashOpt(thisBCCSPMsp.cryptoConfig.IdentityIdentifierHashFunction)
assert.NoError(t, err)
digest, err := thisBCCSPMsp.bccsp.Hash(certFromFile.Raw, hashOpt)
assert.NoError(t, err)

// Compare with the digest computed from the sanitised cert
assert.NotEqual(t, idid.Id, hex.EncodeToString(digest))
}
51 changes: 3 additions & 48 deletions msp/mspimpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,22 +117,7 @@ func (msp *bccspmsp) getIdentityFromConf(idBytes []byte) (Identity, bccsp.Key, e
// get the public key in the right format
certPubK, err := msp.bccsp.KeyImport(cert, &bccsp.X509PublicKeyImportOpts{Temporary: true})

// Use the hash of the identity's certificate as id in the IdentityIdentifier
hashOpt, err := bccsp.GetHashOpt(msp.cryptoConfig.IdentityIdentifierHashFunction)
if err != nil {
return nil, nil, fmt.Errorf("getIdentityFromConf failed getting hash function options [%s]", err)
}

digest, err := msp.bccsp.Hash(cert.Raw, hashOpt)
if err != nil {
return nil, nil, fmt.Errorf("getIdentityFromConf failed hashing raw certificate to compute the id of the IdentityIdentifier [%s]", err)
}

id := &IdentityIdentifier{
Mspid: msp.name,
Id: hex.EncodeToString(digest)}

mspId, err := newIdentity(id, cert, certPubK, msp)
mspId, err := newIdentity(cert, certPubK, msp)
if err != nil {
return nil, nil, err
}
Expand Down Expand Up @@ -173,22 +158,7 @@ func (msp *bccspmsp) getSigningIdentityFromConf(sidInfo *m.SigningIdentityInfo)
return nil, fmt.Errorf("getIdentityFromBytes error: Failed initializing bccspCryptoSigner, err %s", err)
}

// Use the hash of the identity's certificate as id in the IdentityIdentifier
hashOpt, err := bccsp.GetHashOpt(msp.cryptoConfig.IdentityIdentifierHashFunction)
if err != nil {
return nil, fmt.Errorf("getIdentityFromBytes failed getting hash function options [%s]", err)
}

digest, err := msp.bccsp.Hash(idPub.(*identity).cert.Raw, hashOpt)
if err != nil {
return nil, fmt.Errorf("Failed hashing raw certificate to compute the id of the IdentityIdentifier [%s]", err)
}

id := &IdentityIdentifier{
Mspid: msp.name,
Id: hex.EncodeToString(digest)}

return newSigningIdentity(id, idPub.(*identity).cert, idPub.(*identity).pk, peerSigner, msp)
return newSigningIdentity(idPub.(*identity).cert, idPub.(*identity).pk, peerSigner, msp)
}

/*
Expand Down Expand Up @@ -439,27 +409,12 @@ func (msp *bccspmsp) deserializeIdentityInternal(serializedIdentity []byte) (Ide
// We can't do it yet because there is no standardized way
// (yet) to encode the MSP ID into the x.509 body of a cert

// Use the hash of the identity's certificate as id in the IdentityIdentifier
hashOpt, err := bccsp.GetHashOpt(msp.cryptoConfig.IdentityIdentifierHashFunction)
if err != nil {
return nil, fmt.Errorf("Failed getting hash function options [%s]", err)
}

digest, err := msp.bccsp.Hash(cert.Raw, hashOpt)
if err != nil {
return nil, fmt.Errorf("Failed hashing raw certificate to compute the id of the IdentityIdentifier [%s]", err)
}

id := &IdentityIdentifier{
Mspid: msp.name,
Id: hex.EncodeToString(digest)}

pub, err := msp.bccsp.KeyImport(cert, &bccsp.X509PublicKeyImportOpts{Temporary: true})
if err != nil {
return nil, fmt.Errorf("Failed to import certitifacate's public key [%s]", err)
}

return newIdentity(id, cert, pub, msp)
return newIdentity(cert, pub, msp)
}

// SatisfiesPrincipal returns null if the identity matches the principal or an error otherwise
Expand Down
13 changes: 13 additions & 0 deletions msp/testdata/mspid/admincerts/peer0-cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-----BEGIN CERTIFICATE-----
MIIB/zCCAaWgAwIBAgIRAKaex32sim4PQR6kDPEPVnwwCgYIKoZIzj0EAwIwaTEL
MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG
cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRcwFQYDVQQDEw5jYS5leGFt
cGxlLmNvbTAeFw0xNzA3MjYwNDM1MDJaFw0yNzA3MjQwNDM1MDJaMEoxCzAJBgNV
BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp
c2NvMQ4wDAYDVQQDEwVwZWVyMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABPzs
BSdIIB0GrKmKWn0N8mMfxWs2s1D6K+xvTvVJ3wUj3znNBxj+k2j2tpPuJUExt61s
KbpP3GF9/crEahpXXRajTTBLMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAA
MCsGA1UdIwQkMCKAIEvLfQX685pz+rh2q5yCA7e0a/a5IGDuJVHRWfp++HThMAoG
CCqGSM49BAMCA0gAMEUCIH5H9W3tsCrti6tsN9UfY1eeTKtExf/abXhfqfVeRChk
AiEA0GxTPOXVHo0gJpMbHc9B73TL5ZfDhujoDyjb8DToWPQ=
-----END CERTIFICATE-----
14 changes: 14 additions & 0 deletions msp/testdata/mspid/cacerts/ca.example.com-cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-----BEGIN CERTIFICATE-----
MIICMDCCAdagAwIBAgIRANSZuFNkGJoaE5SrI6DW43wwCgYIKoZIzj0EAwIwaTEL
MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG
cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRcwFQYDVQQDEw5jYS5leGFt
cGxlLmNvbTAeFw0xNzA3MjYwNDM1MDJaFw0yNzA3MjQwNDM1MDJaMGkxCzAJBgNV
BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp
c2NvMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEXMBUGA1UEAxMOY2EuZXhhbXBsZS5j
b20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQEuWtLHAvuPjAXo4P6BNHsD+HF
8Ly3ZlKwI4XAl39RPgoqb/zEKx4kNII4jTEvure9x8SFPwnZIAgfWMix3sgPo18w
XTAOBgNVHQ8BAf8EBAMCAaYwDwYDVR0lBAgwBgYEVR0lADAPBgNVHRMBAf8EBTAD
AQH/MCkGA1UdDgQiBCBLy30F+vOac/q4dqucggO3tGv2uSBg7iVR0Vn6fvh04TAK
BggqhkjOPQQDAgNIADBFAiBrFIVo3QTOqxc8ojUkK5JDtwF+u+FX1k72WbNazxJf
uAIhAO3JrGN3lwrLrADY1l+A/imYum/0xynPAUPuBG+5TI1/
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgyA3kupzpQJ5OKG2+
dVb3d01tHlqO0rlDcrkxXa3a5ZqhRANCAAT87AUnSCAdBqypilp9DfJjH8VrNrNQ
+ivsb071Sd8FI985zQcY/pNo9raT7iVBMbetbCm6T9xhff3KxGoaV10W
-----END PRIVATE KEY-----
13 changes: 13 additions & 0 deletions msp/testdata/mspid/signcerts/peer0-cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-----BEGIN CERTIFICATE-----
MIIB/zCCAaWgAwIBAgIRAKaex32sim4PQR6kDPEPVnwwCgYIKoZIzj0EAwIwaTEL
MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG
cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRcwFQYDVQQDEw5jYS5leGFt
cGxlLmNvbTAeFw0xNzA3MjYwNDM1MDJaFw0yNzA3MjQwNDM1MDJaMEoxCzAJBgNV
BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp
c2NvMQ4wDAYDVQQDEwVwZWVyMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABPzs
BSdIIB0GrKmKWn0N8mMfxWs2s1D6K+xvTvVJ3wUj3znNBxj+k2j2tpPuJUExt61s
KbpP3GF9/crEahpXXRajTTBLMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAA
MCsGA1UdIwQkMCKAIEvLfQX685pz+rh2q5yCA7e0a/a5IGDuJVHRWfp++HThMAoG
CCqGSM49BAMCA0gAMEUCIH5H9W3tsCrti6tsN9UfY1eeTKtExf/abXhfqfVeRChk
AiEA0GxTPOXVHo0gJpMbHc9B73TL5ZfDhujoDyjb8DToWPQ=
-----END CERTIFICATE-----
14 changes: 14 additions & 0 deletions msp/testdata/mspid/tlscacerts/ca.example.com-cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-----BEGIN CERTIFICATE-----
MIICMDCCAdWgAwIBAgIQWoNSU41CWlCJJTrXFyzzKzAKBggqhkjOPQQDAjBpMQsw
CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy
YW5jaXNjbzEUMBIGA1UEChMLZXhhbXBsZS5jb20xFzAVBgNVBAMTDmNhLmV4YW1w
bGUuY29tMB4XDTE3MDcyNjA0MzUwMloXDTI3MDcyNDA0MzUwMlowaTELMAkGA1UE
BhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lz
Y28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRcwFQYDVQQDEw5jYS5leGFtcGxlLmNv
bTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGBCZG9VRTIsWXlMBA7YQzYzuZHz
TaEvsGtcAtpdtpdvOTYa10Tm2EdUbfeadyYdIMTyMp9JnjHntm21+cORphWjXzBd
MA4GA1UdDwEB/wQEAwIBpjAPBgNVHSUECDAGBgRVHSUAMA8GA1UdEwEB/wQFMAMB
Af8wKQYDVR0OBCIEIDhvAhEY4NU7AI1PN8pJEp1s7WoWCjoJ/CgZ/loJ+rxYMAoG
CCqGSM49BAMCA0kAMEYCIQDGl5bN8g54ttrvkT0sSnZyCLFpPaaKjAfDR36FsB6k
oAIhAIKnO8mcocALwvao07Ll7FvLVQJp97+VU8/MwM3H44oL
-----END CERTIFICATE-----

0 comments on commit 5a65700

Please sign in to comment.