github.com/cactusblossom/fabric-ca@v0.0.0-20200611062428-0082fc643826/lib/test-util.go (about) 1 /* 2 Copyright IBM Corp. 2016 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 lib 18 19 import ( 20 "crypto/rand" 21 "crypto/x509" 22 "crypto/x509/pkix" 23 "encoding/pem" 24 "errors" 25 "fmt" 26 "io" 27 "io/ioutil" 28 "math/big" 29 "os" 30 "path" 31 "strconv" 32 "testing" 33 "time" 34 35 "github.com/cloudflare/cfssl/config" 36 ) 37 38 const ( 39 rootPort = 7075 40 rootDir = "rootDir" 41 rootClientDir = "rootClientDir" 42 intermediatePort = 7076 43 intermediateDir = "intDir" 44 testdataDir = "../testdata" 45 ) 46 47 func getRootServerURL() string { 48 return fmt.Sprintf("http://admin:adminpw@localhost:%d", rootPort) 49 } 50 51 // TestGetRootServer creates a server with root configuration 52 func TestGetRootServer(t *testing.T) *Server { 53 return TestGetServer(rootPort, rootDir, "", -1, t) 54 } 55 56 // TestGetIntermediateServer creates a server with intermediate server configuration 57 func TestGetIntermediateServer(idx int, t *testing.T) *Server { 58 return TestGetServer( 59 intermediatePort, 60 path.Join(intermediateDir, strconv.Itoa(idx)), 61 getRootServerURL(), 62 -1, 63 t) 64 } 65 66 // TestGetServer creates and returns a pointer to a server struct 67 func TestGetServer(port int, home, parentURL string, maxEnroll int, t *testing.T) *Server { 68 return TestGetServer2(home != testdataDir, port, home, parentURL, maxEnroll, t) 69 } 70 71 // TestGetServer2 creates and returns a pointer to a server struct, with an option of 72 // whether or not to remove the home directory first 73 func TestGetServer2(deleteHome bool, port int, home, parentURL string, maxEnroll int, t *testing.T) *Server { 74 if deleteHome { 75 os.RemoveAll(home) 76 } 77 affiliations := map[string]interface{}{ 78 "hyperledger": map[string]interface{}{ 79 "fabric": []string{"ledger", "orderer", "security"}, 80 "fabric-ca": nil, 81 "sdk": nil, 82 }, 83 "org2": []string{"dept1"}, 84 "org1": nil, 85 "org2dept1": nil, 86 } 87 profiles := map[string]*config.SigningProfile{ 88 "tls": &config.SigningProfile{ 89 Usage: []string{"signing", "key encipherment", "server auth", "client auth", "key agreement"}, 90 ExpiryString: "8760h", 91 }, 92 "ca": &config.SigningProfile{ 93 Usage: []string{"cert sign", "crl sign"}, 94 ExpiryString: "8760h", 95 CAConstraint: config.CAConstraint{ 96 IsCA: true, 97 MaxPathLen: 0, 98 }, 99 }, 100 } 101 defaultProfile := &config.SigningProfile{ 102 Usage: []string{"cert sign"}, 103 ExpiryString: "8760h", 104 } 105 srv := &Server{ 106 Config: &ServerConfig{ 107 Port: port, 108 Debug: true, 109 }, 110 CA: CA{ 111 Config: &CAConfig{ 112 Intermediate: IntermediateCA{ 113 ParentServer: ParentServer{ 114 URL: parentURL, 115 }, 116 }, 117 Affiliations: affiliations, 118 Registry: CAConfigRegistry{ 119 MaxEnrollments: maxEnroll, 120 }, 121 Signing: &config.Signing{ 122 Profiles: profiles, 123 Default: defaultProfile, 124 }, 125 Version: "1.1.0", // The default test server/ca should use the latest version 126 }, 127 }, 128 HomeDir: home, 129 } 130 // The bootstrap user's affiliation is the empty string, which 131 // means the user is at the affiliation root 132 err := srv.RegisterBootstrapUser("admin", "adminpw", "") 133 if err != nil { 134 t.Errorf("Failed to register bootstrap user: %s", err) 135 return nil 136 } 137 return srv 138 } 139 140 // CopyFile copies a file 141 func CopyFile(src, dst string) error { 142 srcFile, err := os.Open(src) 143 if err != nil { 144 return err 145 } 146 147 defer srcFile.Close() 148 149 destFile, err := os.Create(dst) 150 if err != nil { 151 return err 152 } 153 154 defer destFile.Close() 155 156 _, err = io.Copy(destFile, srcFile) 157 if err != nil { 158 return err 159 } 160 161 err = destFile.Sync() 162 if err != nil { 163 return err 164 } 165 return nil 166 } 167 168 // GenerateECDSATestCert generates EC based certificate for testing purposes 169 func GenerateECDSATestCert() error { 170 template := &x509.Certificate{ 171 IsCA: true, 172 BasicConstraintsValid: true, 173 SubjectKeyId: []byte{1, 2, 3}, 174 SerialNumber: big.NewInt(1234), 175 Subject: pkix.Name{ 176 Country: []string{"US"}, 177 Organization: []string{"IBM"}, 178 }, 179 NotBefore: time.Now(), 180 NotAfter: time.Now().AddDate(15, 0, 0), 181 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, 182 KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, 183 } 184 185 privKey, err := ioutil.ReadFile("../testdata/ec_key.pem") 186 if err != nil { 187 return err 188 } 189 190 decoded, _ := pem.Decode(privKey) 191 if decoded == nil { 192 return errors.New("Failed to decode the PEM-encoded ECDSA key") 193 } 194 privateKey, err := x509.ParseECPrivateKey(decoded.Bytes) 195 if err != nil { 196 return err 197 } 198 199 publicKey := &privateKey.PublicKey 200 201 var parent = template 202 cert, err := x509.CreateCertificate(rand.Reader, template, parent, publicKey, privateKey) 203 if err != nil { 204 return err 205 } 206 207 certOut, err := os.Create("../testdata/ec_cert.pem") 208 if err != nil { 209 return err 210 } 211 pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: cert}) 212 213 return nil 214 } 215 216 // Currently not being used anywhere, commenting it out for right now 217 // it was just bringing test coverage. 218 219 // StopAndCleanupServer stops the server and removes the server's home directory 220 // func StopAndCleanupServer(t *testing.T, srv *Server) { 221 // if srv != nil { 222 // defer os.RemoveAll(srv.HomeDir) 223 // err := srv.Stop() 224 // if err != nil { 225 // t.Errorf("Server stop failed: %s", err) 226 // } 227 // } 228 // } 229 230 // TestGetRootClient returns a Fabric CA client that is meant for a root Fabric CA server 231 func TestGetRootClient() *Client { 232 return TestGetClient(rootPort, rootClientDir) 233 } 234 235 // TestGetClient returns a Fabric CA client 236 func TestGetClient(port int, home string) *Client { 237 return &Client{ 238 Config: &ClientConfig{URL: fmt.Sprintf("http://localhost:%d", port)}, 239 HomeDir: home, 240 } 241 }