diff --git a/common/tools/armageddon/armageddon.go b/common/tools/armageddon/armageddon.go index 3e39f913..a14365ac 100644 --- a/common/tools/armageddon/armageddon.go +++ b/common/tools/armageddon/armageddon.go @@ -347,8 +347,8 @@ func generateConfigAndCrypto(genConfigFile **os.File, outputDir *string, sampleC } for i := range sharedConfig.PartiesConfig { - userTLSPrivateKeyPath := filepath.Join(*outputDir, "crypto", "ordererOrganizations", fmt.Sprintf("org%d", i+1), "users", "user-key.pem") - userTLSCertPath := filepath.Join(*outputDir, "crypto", "ordererOrganizations", fmt.Sprintf("org%d", i+1), "users", "user-tls-cert.pem") + userTLSPrivateKeyPath := filepath.Join(*outputDir, "crypto", "ordererOrganizations", fmt.Sprintf("org%d", i+1), "users", "user", "tls", "user-key.pem") + userTLSCertPath := filepath.Join(*outputDir, "crypto", "ordererOrganizations", fmt.Sprintf("org%d", i+1), "users", "user", "tls", "user-tls-cert.pem") userConfig, err := NewUserConfig(userTLSPrivateKeyPath, userTLSCertPath, tlsCACertsBytesPartiesCollection, networkConfig) if err != nil { diff --git a/common/tools/armageddon/armageddon_test.go b/common/tools/armageddon/armageddon_test.go index 9438d035..1bcbbe9d 100644 --- a/common/tools/armageddon/armageddon_test.go +++ b/common/tools/armageddon/armageddon_test.go @@ -577,13 +577,50 @@ func checkCryptoDir(outputDir string) error { // check users dir usersDir := filepath.Join(orgDir, "users") - files, err := os.ReadDir(usersDir) + if _, err := os.Stat(usersDir); os.IsNotExist(err) { + return fmt.Errorf("missing directory: %s\n", usersDir) + } + users, err := os.ReadDir(usersDir) if err != nil { return fmt.Errorf("error reading directory %s\n", usersDir) } - for _, file := range files { - if !strings.HasSuffix(file.Name(), ".pem") { - return fmt.Errorf("error reading %s files, suffix file is not pem\n", filepath.Join(orgDir, usersDir)) + for _, user := range users { + userMSPPath := filepath.Join(orgDir, "users", user.Name(), "msp") + if _, err := os.Stat(userMSPPath); os.IsNotExist(err) { + return fmt.Errorf("missing directory: %s\n", userMSPPath) + } + + requiredMSPSubDirs := []string{"cacerts", "intermediatecerts", "admincerts", "keystore", "signcerts", "tlscacerts", "tlsintermediatecerts"} + for _, mspSubDir := range requiredMSPSubDirs { + mspSubDirPath := filepath.Join(userMSPPath, mspSubDir) + if _, err := os.Stat(mspSubDirPath); os.IsNotExist(err) { + return fmt.Errorf("missing directory: %s\n", mspSubDirPath) + } + if mspSubDir == "keystore" || mspSubDir == "signcerts" { + files, err := os.ReadDir(mspSubDirPath) + if err != nil { + return fmt.Errorf("error reading directory %s\n", mspSubDirPath) + } + for _, file := range files { + if !strings.HasSuffix(file.Name(), ".pem") && !strings.Contains(file.Name(), "priv_sk") { + return fmt.Errorf("error reading %s files, expect pem files or file name priv_sk \n", mspSubDirPath) + } + } + } + } + + userTLSPath := filepath.Join(orgDir, "users", user.Name(), "tls") + if _, err := os.Stat(userTLSPath); os.IsNotExist(err) { + return fmt.Errorf("missing directory: %s\n", userTLSPath) + } + files, err := os.ReadDir(userTLSPath) + if err != nil { + return fmt.Errorf("error reading directory %s\n", userTLSPath) + } + for _, file := range files { + if !strings.HasSuffix(file.Name(), ".pem") { + return fmt.Errorf("error reading %s files, suffix file is not pem\n", userTLSPath) + } } } @@ -616,7 +653,7 @@ func checkCryptoDir(outputDir string) error { return fmt.Errorf("missing directory: %s\n", mspSubDirPath) } if mspSubDir == "keystore" || mspSubDir == "signcerts" { - files, err = os.ReadDir(mspSubDirPath) + files, err := os.ReadDir(mspSubDirPath) if err != nil { return fmt.Errorf("error reading directory %s\n", mspSubDirPath) } @@ -632,7 +669,7 @@ func checkCryptoDir(outputDir string) error { if _, err := os.Stat(tlsPath); os.IsNotExist(err) { return fmt.Errorf("missing directory: %s\n", tlsPath) } - files, err = os.ReadDir(tlsPath) + files, err := os.ReadDir(tlsPath) if err != nil { return fmt.Errorf("error reading directory %s\n", tlsPath) } diff --git a/common/tools/armageddon/cryptogen.go b/common/tools/armageddon/cryptogen.go index ff12fdfb..93fa1869 100644 --- a/common/tools/armageddon/cryptogen.go +++ b/common/tools/armageddon/cryptogen.go @@ -45,29 +45,39 @@ const ( // dir // └── crypto // -// └── ordererOrganizations -// └── org{partyID} -// ├── ca -// ├── tlsca -// ├── orderers -// │ └── party{partyID} -// │ ├── router -// │ │ ├── tls -// │ │ └── msp -// │ │ ├── cacerts -// │ │ ├── intermediatecerts -// │ │ ├── admincerts (ignored) -// │ │ ├── keystore -// │ │ ├── signcerts -// │ │ ├── tlscacerts -// │ │ └── tlsintermediatecerts -// │ ├── batcher1 -// │ ├── batcher2 -// │ ├── ... -// │ ├── batcher{shards} -// │ ├── consenter -// │ └── assembler -// └── users +// └── ordererOrganizations +// └── org{partyID} +// ├── ca +// ├── tlsca +// ├── orderers +// │ └── party{partyID} +// │ ├── router +// │ │ ├── tls +// │ │ └── msp +// │ │ ├── cacerts +// │ │ ├── intermediatecerts +// │ │ ├── admincerts (ignored) +// │ │ ├── keystore +// │ │ ├── signcerts +// │ │ ├── tlscacerts +// │ │ └── tlsintermediatecerts +// │ ├── batcher1 +// │ ├── batcher2 +// │ ├── ... +// │ ├── batcher{shards} +// │ ├── consenter +// │ └── assembler +// └── users +// └── user (admin, orderer loadgen) +// ├── tls +// └── msp +// ├── cacerts +// ├── intermediatecerts +// ├── admincerts (ignored) +// ├── keystore +// ├── signcerts +// ├── tlscacerts +// └── tlsintermediatecerts func GenerateCryptoConfig(networkConfig *genconfig.Network, outputDir string) error { // create folder structure for the crypto files err := generateNetworkCryptoConfigFolderStructure(outputDir, networkConfig) @@ -182,6 +192,12 @@ func createNetworkCryptoMaterial(dir string, network *genconfig.Network) error { if err != nil { return err } + + // signing crypto to user + err = createUserSignCertAndPrivateKey(signCA, dir, party.ID, nil) + if err != nil { + return err + } } return nil } @@ -245,11 +261,11 @@ func createUserTLSCertKeyPair(ca *ca.CA, dir string, partyID types.PartyID, node return fmt.Errorf("err: %s, failed marshaling private key for user for party %d", err, partyID) } - ca.SignCertificate(filepath.Join(dir, "crypto", "ordererOrganizations", fmt.Sprintf("org%d", partyID), "users"), "user-tls", nil, nodesIPs, getPublicKey(privateKey), x509.KeyUsageKeyEncipherment|x509.KeyUsageDigitalSignature, []x509.ExtKeyUsage{ + ca.SignCertificate(filepath.Join(dir, "crypto", "ordererOrganizations", fmt.Sprintf("org%d", partyID), "users", "user", "tls"), "user-tls", nil, nodesIPs, getPublicKey(privateKey), x509.KeyUsageKeyEncipherment|x509.KeyUsageDigitalSignature, []x509.ExtKeyUsage{ x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth, }) - err = writePEMToFile(filepath.Join(dir, "crypto", "ordererOrganizations", fmt.Sprintf("org%d", partyID), "users", "user-key.pem"), "PRIVATE KEY", privateKeyBytes) + err = writePEMToFile(filepath.Join(dir, "crypto", "ordererOrganizations", fmt.Sprintf("org%d", partyID), "users", "user", "tls", "user-key.pem"), "PRIVATE KEY", privateKeyBytes) if err != nil { return err } @@ -276,6 +292,25 @@ func createSignCertAndPrivateKeyForNode(ca *ca.CA, dir string, endpoint string, return nil } +// createUserSignCertAndPrivateKey creates for user a signed certificate with a corresponding private key used for signing and write them into files. +func createUserSignCertAndPrivateKey(ca *ca.CA, dir string, partyID types.PartyID, nodesIPs []string) error { + privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + return fmt.Errorf("err: %s, failed creating private key for user of party %d", err, partyID) + } + privateKeyBytes, err := x509.MarshalPKCS8PrivateKey(privateKey) + if err != nil { + return fmt.Errorf("err: %s, failed marshaling private key for user of party %d", err, partyID) + } + + ca.SignCertificate(filepath.Join(dir, "crypto", "ordererOrganizations", fmt.Sprintf("org%d", partyID), "users", "user", "msp", "signcerts"), "sign", nil, nodesIPs, getPublicKey(privateKey), x509.KeyUsageDigitalSignature, []x509.ExtKeyUsage{}) + err = writePEMToFile(filepath.Join(dir, "crypto", "ordererOrganizations", fmt.Sprintf("org%d", partyID), "users", "user", "msp", "keystore", "priv_sk"), "PRIVATE KEY", privateKeyBytes) + if err != nil { + return err + } + return nil +} + // generateNetworkCryptoConfigFolderStructure creates folders where the crypto material is written to. func generateNetworkCryptoConfigFolderStructure(dir string, network *genconfig.Network) error { var folders []string @@ -333,6 +368,12 @@ func generateOrdererOrg(rootDir string, folders []string, partyID int, shards in } folders = append(folders, filepath.Join(orgDir, "users")) + userMSPPath := filepath.Join(orgDir, "users", "user", "msp") + folders = append(folders, userMSPPath) + for _, subDir := range mspSubDirs { + folders = append(folders, filepath.Join(userMSPPath, subDir)) + } + folders = append(folders, filepath.Join(orgDir, "users", "user", "tls")) return folders }