github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/msp/configbuilder.go (about) 1 /* 2 Copyright IBM Corp. 2017 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package msp 18 19 import ( 20 "fmt" 21 "io/ioutil" 22 23 "github.com/golang/protobuf/proto" 24 25 "encoding/pem" 26 "path/filepath" 27 28 "os" 29 30 "github.com/hyperledger/fabric/bccsp" 31 "github.com/hyperledger/fabric/bccsp/factory" 32 "github.com/hyperledger/fabric/protos/msp" 33 "gopkg.in/yaml.v2" 34 ) 35 36 type OrganizationalUnitIdentifiersConfiguration struct { 37 Certificate string `yaml:"Certificate,omitempty"` 38 OrganizationalUnitIdentifier string `yaml:"OrganizationalUnitIdentifier,omitempty"` 39 } 40 41 type Configuration struct { 42 OrganizationalUnitIdentifiers []*OrganizationalUnitIdentifiersConfiguration `yaml:"OrganizationalUnitIdentifiers,omitempty"` 43 } 44 45 func readFile(file string) ([]byte, error) { 46 fileCont, err := ioutil.ReadFile(file) 47 if err != nil { 48 return nil, fmt.Errorf("Could not read file %s, err %s", file, err) 49 } 50 51 return fileCont, nil 52 } 53 54 func readPemFile(file string) ([]byte, error) { 55 bytes, err := readFile(file) 56 if err != nil { 57 return nil, err 58 } 59 60 b, _ := pem.Decode(bytes) 61 if b == nil { // TODO: also check that the type is what we expect (cert vs key..) 62 return nil, fmt.Errorf("No pem content for file %s", file) 63 } 64 65 return bytes, nil 66 } 67 68 func getPemMaterialFromDir(dir string) ([][]byte, error) { 69 mspLogger.Debugf("Reading directory %s", dir) 70 71 _, err := os.Stat(dir) 72 if os.IsNotExist(err) { 73 return nil, err 74 } 75 76 content := make([][]byte, 0) 77 files, err := ioutil.ReadDir(dir) 78 if err != nil { 79 return nil, fmt.Errorf("Could not read directory %s, err %s", err, dir) 80 } 81 82 for _, f := range files { 83 if f.IsDir() { 84 continue 85 } 86 87 fullName := filepath.Join(dir, string(filepath.Separator), f.Name()) 88 mspLogger.Debugf("Inspecting file %s", fullName) 89 90 item, err := readPemFile(fullName) 91 if err != nil { 92 mspLogger.Warningf("Failed readgin file %s: %s", fullName, err) 93 continue 94 } 95 96 content = append(content, item) 97 } 98 99 return content, nil 100 } 101 102 const ( 103 cacerts = "cacerts" 104 admincerts = "admincerts" 105 signcerts = "signcerts" 106 keystore = "keystore" 107 intermediatecerts = "intermediatecerts" 108 crlsfolder = "crls" 109 configfilename = "config.yaml" 110 tlscacerts = "tlscacerts" 111 tlsintermediatecerts = "tlsintermediatecerts" 112 ) 113 114 func SetupBCCSPKeystoreConfig(bccspConfig *factory.FactoryOpts, keystoreDir string) *factory.FactoryOpts { 115 if bccspConfig == nil { 116 bccspConfig = factory.GetDefaultOpts() 117 } 118 119 if bccspConfig.ProviderName == "SW" { 120 if bccspConfig.SwOpts == nil { 121 bccspConfig.SwOpts = factory.GetDefaultOpts().SwOpts 122 } 123 124 // Only override the KeyStorePath if it was left empty 125 if bccspConfig.SwOpts.FileKeystore == nil || 126 bccspConfig.SwOpts.FileKeystore.KeyStorePath == "" { 127 bccspConfig.SwOpts.Ephemeral = false 128 bccspConfig.SwOpts.FileKeystore = &factory.FileKeystoreOpts{KeyStorePath: keystoreDir} 129 } 130 } 131 132 return bccspConfig 133 } 134 135 func GetLocalMspConfig(dir string, bccspConfig *factory.FactoryOpts, ID string) (*msp.MSPConfig, error) { 136 signcertDir := filepath.Join(dir, signcerts) 137 keystoreDir := filepath.Join(dir, keystore) 138 bccspConfig = SetupBCCSPKeystoreConfig(bccspConfig, keystoreDir) 139 140 err := factory.InitFactories(bccspConfig) 141 if err != nil { 142 return nil, fmt.Errorf("Could not initialize BCCSP Factories [%s]", err) 143 } 144 145 signcert, err := getPemMaterialFromDir(signcertDir) 146 if err != nil || len(signcert) == 0 { 147 return nil, fmt.Errorf("Could not load a valid signer certificate from directory %s, err %s", signcertDir, err) 148 } 149 150 /* FIXME: for now we're making the following assumptions 151 1) there is exactly one signing cert 152 2) BCCSP's KeyStore has the private key that matches SKI of 153 signing cert 154 */ 155 156 sigid := &msp.SigningIdentityInfo{PublicSigner: signcert[0], PrivateSigner: nil} 157 158 return getMspConfig(dir, ID, sigid) 159 } 160 161 func GetVerifyingMspConfig(dir string, ID string) (*msp.MSPConfig, error) { 162 return getMspConfig(dir, ID, nil) 163 } 164 165 func getMspConfig(dir string, ID string, sigid *msp.SigningIdentityInfo) (*msp.MSPConfig, error) { 166 cacertDir := filepath.Join(dir, cacerts) 167 admincertDir := filepath.Join(dir, admincerts) 168 intermediatecertsDir := filepath.Join(dir, intermediatecerts) 169 crlsDir := filepath.Join(dir, crlsfolder) 170 configFile := filepath.Join(dir, configfilename) 171 tlscacertDir := filepath.Join(dir, tlscacerts) 172 tlsintermediatecertsDir := filepath.Join(dir, tlsintermediatecerts) 173 174 cacerts, err := getPemMaterialFromDir(cacertDir) 175 if err != nil || len(cacerts) == 0 { 176 return nil, fmt.Errorf("Could not load a valid ca certificate from directory %s, err %s", cacertDir, err) 177 } 178 179 admincert, err := getPemMaterialFromDir(admincertDir) 180 if err != nil || len(admincert) == 0 { 181 return nil, fmt.Errorf("Could not load a valid admin certificate from directory %s, err %s", admincertDir, err) 182 } 183 184 intermediatecerts, err := getPemMaterialFromDir(intermediatecertsDir) 185 if os.IsNotExist(err) { 186 mspLogger.Debugf("Intermediate certs folder not found at [%s]. Skipping. [%s]", intermediatecertsDir, err) 187 } else if err != nil { 188 return nil, fmt.Errorf("Failed loading intermediate ca certs at [%s]: [%s]", intermediatecertsDir, err) 189 } 190 191 tlsCACerts, err := getPemMaterialFromDir(tlscacertDir) 192 tlsIntermediateCerts := [][]byte{} 193 if os.IsNotExist(err) { 194 mspLogger.Debugf("TLS CA certs folder not found at [%s]. Skipping and ignoring TLS intermediate CA folder. [%s]", tlsintermediatecertsDir, err) 195 } else if err != nil { 196 return nil, fmt.Errorf("Failed loading TLS ca certs at [%s]: [%s]", tlsintermediatecertsDir, err) 197 } else if len(tlsCACerts) != 0 { 198 tlsIntermediateCerts, err = getPemMaterialFromDir(tlsintermediatecertsDir) 199 if os.IsNotExist(err) { 200 mspLogger.Debugf("TLS intermediate certs folder not found at [%s]. Skipping. [%s]", tlsintermediatecertsDir, err) 201 } else if err != nil { 202 return nil, fmt.Errorf("Failed loading TLS intermediate ca certs at [%s]: [%s]", tlsintermediatecertsDir, err) 203 } 204 } else { 205 mspLogger.Debugf("TLS CA certs folder at [%s] is empty. Skipping.", tlsintermediatecertsDir) 206 } 207 208 crls, err := getPemMaterialFromDir(crlsDir) 209 if os.IsNotExist(err) { 210 mspLogger.Debugf("crls folder not found at [%s]. Skipping. [%s]", crlsDir, err) 211 } else if err != nil { 212 return nil, fmt.Errorf("Failed loading crls at [%s]: [%s]", crlsDir, err) 213 } 214 215 // Load configuration file 216 // if the configuration file is there then load it 217 // otherwise skip it 218 var ouis []*msp.FabricOUIdentifier 219 _, err = os.Stat(configFile) 220 if err == nil { 221 // load the file, if there is a failure in loading it then 222 // return an error 223 raw, err := ioutil.ReadFile(configFile) 224 if err != nil { 225 return nil, fmt.Errorf("Failed loading configuration file at [%s]: [%s]", configFile, err) 226 } 227 228 configuration := Configuration{} 229 err = yaml.Unmarshal(raw, &configuration) 230 if err != nil { 231 return nil, fmt.Errorf("Failed unmarshalling configuration file at [%s]: [%s]", configFile, err) 232 } 233 234 // Prepare OrganizationalUnitIdentifiers 235 if len(configuration.OrganizationalUnitIdentifiers) > 0 { 236 for _, ouID := range configuration.OrganizationalUnitIdentifiers { 237 f := filepath.Join(dir, ouID.Certificate) 238 raw, err = ioutil.ReadFile(f) 239 if err != nil { 240 return nil, fmt.Errorf("Failed loading OrganizationalUnit certificate at [%s]: [%s]", f, err) 241 } 242 oui := &msp.FabricOUIdentifier{ 243 Certificate: raw, 244 OrganizationalUnitIdentifier: ouID.OrganizationalUnitIdentifier, 245 } 246 ouis = append(ouis, oui) 247 } 248 } 249 } else { 250 mspLogger.Debugf("MSP configuration file not found at [%s]: [%s]", configFile, err) 251 } 252 253 // Set FabricCryptoConfig 254 cryptoConfig := &msp.FabricCryptoConfig{ 255 SignatureHashFamily: bccsp.SHA2, 256 IdentityIdentifierHashFunction: bccsp.SHA256, 257 } 258 259 // Compose FabricMSPConfig 260 fmspconf := &msp.FabricMSPConfig{ 261 Admins: admincert, 262 RootCerts: cacerts, 263 IntermediateCerts: intermediatecerts, 264 SigningIdentity: sigid, 265 Name: ID, 266 OrganizationalUnitIdentifiers: ouis, 267 RevocationList: crls, 268 CryptoConfig: cryptoConfig, 269 TlsRootCerts: tlsCACerts, 270 TlsIntermediateCerts: tlsIntermediateCerts, 271 } 272 273 fmpsjs, _ := proto.Marshal(fmspconf) 274 275 mspconf := &msp.MSPConfig{Config: fmpsjs, Type: int32(FABRIC)} 276 277 return mspconf, nil 278 }