github.com/tenywen/fabric@v1.0.0-beta.0.20170620030522-a5b1ed380643/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 ) 111 112 func SetupBCCSPKeystoreConfig(bccspConfig *factory.FactoryOpts, keystoreDir string) *factory.FactoryOpts { 113 if bccspConfig == nil { 114 bccspConfig = factory.GetDefaultOpts() 115 } 116 117 if bccspConfig.ProviderName == "SW" { 118 if bccspConfig.SwOpts == nil { 119 bccspConfig.SwOpts = factory.GetDefaultOpts().SwOpts 120 } 121 122 // Only override the KeyStorePath if it was left empty 123 if bccspConfig.SwOpts.FileKeystore == nil || 124 bccspConfig.SwOpts.FileKeystore.KeyStorePath == "" { 125 bccspConfig.SwOpts.Ephemeral = false 126 bccspConfig.SwOpts.FileKeystore = &factory.FileKeystoreOpts{KeyStorePath: keystoreDir} 127 } 128 } 129 130 return bccspConfig 131 } 132 133 func GetLocalMspConfig(dir string, bccspConfig *factory.FactoryOpts, ID string) (*msp.MSPConfig, error) { 134 signcertDir := filepath.Join(dir, signcerts) 135 keystoreDir := filepath.Join(dir, keystore) 136 bccspConfig = SetupBCCSPKeystoreConfig(bccspConfig, keystoreDir) 137 138 err := factory.InitFactories(bccspConfig) 139 if err != nil { 140 return nil, fmt.Errorf("Could not initialize BCCSP Factories [%s]", err) 141 } 142 143 signcert, err := getPemMaterialFromDir(signcertDir) 144 if err != nil || len(signcert) == 0 { 145 return nil, fmt.Errorf("Could not load a valid signer certificate from directory %s, err %s", signcertDir, err) 146 } 147 148 /* FIXME: for now we're making the following assumptions 149 1) there is exactly one signing cert 150 2) BCCSP's KeyStore has the private key that matches SKI of 151 signing cert 152 */ 153 154 sigid := &msp.SigningIdentityInfo{PublicSigner: signcert[0], PrivateSigner: nil} 155 156 return getMspConfig(dir, ID, sigid) 157 } 158 159 func GetVerifyingMspConfig(dir string, ID string) (*msp.MSPConfig, error) { 160 return getMspConfig(dir, ID, nil) 161 } 162 163 func getMspConfig(dir string, ID string, sigid *msp.SigningIdentityInfo) (*msp.MSPConfig, error) { 164 cacertDir := filepath.Join(dir, cacerts) 165 admincertDir := filepath.Join(dir, admincerts) 166 intermediatecertsDir := filepath.Join(dir, intermediatecerts) 167 crlsDir := filepath.Join(dir, crlsfolder) 168 configFile := filepath.Join(dir, configfilename) 169 170 cacerts, err := getPemMaterialFromDir(cacertDir) 171 if err != nil || len(cacerts) == 0 { 172 return nil, fmt.Errorf("Could not load a valid ca certificate from directory %s, err %s", cacertDir, err) 173 } 174 175 admincert, err := getPemMaterialFromDir(admincertDir) 176 if err != nil || len(admincert) == 0 { 177 return nil, fmt.Errorf("Could not load a valid admin certificate from directory %s, err %s", admincertDir, err) 178 } 179 180 intermediatecert, err := getPemMaterialFromDir(intermediatecertsDir) 181 if os.IsNotExist(err) { 182 mspLogger.Infof("intermediate certs folder not found at [%s]. Skipping.: [%s]", intermediatecertsDir, err) 183 } else if err != nil { 184 return nil, fmt.Errorf("Failed loading intermediate ca certs at [%s]: [%s]", intermediatecertsDir, err) 185 } 186 187 crls, err := getPemMaterialFromDir(crlsDir) 188 if os.IsNotExist(err) { 189 mspLogger.Infof("crls folder not found at [%s]. Skipping.: [%s]", intermediatecertsDir, err) 190 } else if err != nil { 191 return nil, fmt.Errorf("Failed loading crls ca certs at [%s]: [%s]", intermediatecertsDir, err) 192 } 193 194 // Load configuration file 195 // if the configuration file is there then load it 196 // otherwise skip it 197 var ouis []*msp.FabricOUIdentifier 198 _, err = os.Stat(configFile) 199 if err == nil { 200 // load the file, if there is a failure in loading it then 201 // return an error 202 raw, err := ioutil.ReadFile(configFile) 203 if err != nil { 204 return nil, fmt.Errorf("Failed loading configuration file at [%s]: [%s]", configFile, err) 205 } 206 207 configuration := Configuration{} 208 err = yaml.Unmarshal(raw, &configuration) 209 if err != nil { 210 return nil, fmt.Errorf("Failed unmarshalling configuration file at [%s]: [%s]", configFile, err) 211 } 212 213 // Prepare OrganizationalUnitIdentifiers 214 if len(configuration.OrganizationalUnitIdentifiers) > 0 { 215 for _, ouID := range configuration.OrganizationalUnitIdentifiers { 216 f := filepath.Join(dir, ouID.Certificate) 217 raw, err = ioutil.ReadFile(f) 218 if err != nil { 219 return nil, fmt.Errorf("Failed loading OrganizationalUnit certificate at [%s]: [%s]", f, err) 220 } 221 oui := &msp.FabricOUIdentifier{ 222 Certificate: raw, 223 OrganizationalUnitIdentifier: ouID.OrganizationalUnitIdentifier, 224 } 225 ouis = append(ouis, oui) 226 } 227 } 228 } else { 229 mspLogger.Infof("MSP configuration file not found at [%s]: [%s]", configFile, err) 230 } 231 232 // Set FabricCryptoConfig 233 cryptoConfig := &msp.FabricCryptoConfig{ 234 SignatureHashFamily: bccsp.SHA2, 235 IdentityIdentifierHashFunction: bccsp.SHA256, 236 } 237 238 // Compose FabricMSPConfig 239 fmspconf := &msp.FabricMSPConfig{ 240 Admins: admincert, 241 RootCerts: cacerts, 242 IntermediateCerts: intermediatecert, 243 SigningIdentity: sigid, 244 Name: ID, 245 OrganizationalUnitIdentifiers: ouis, 246 RevocationList: crls, 247 CryptoConfig: cryptoConfig} 248 249 fmpsjs, _ := proto.Marshal(fmspconf) 250 251 mspconf := &msp.MSPConfig{Config: fmpsjs, Type: int32(FABRIC)} 252 253 return mspconf, nil 254 }