github.com/IBM-Blockchain/fabric-operator@v1.0.4/pkg/initializer/ca/ca_test.go (about)

     1  /*
     2   * Copyright contributors to the Hyperledger Fabric Operator project
     3   *
     4   * SPDX-License-Identifier: Apache-2.0
     5   *
     6   * Licensed under the Apache License, Version 2.0 (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at:
     9   *
    10   * 	  http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing, software
    13   * distributed under the License is distributed on an "AS IS" BASIS,
    14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15   * See the License for the specific language governing permissions and
    16   * limitations under the License.
    17   */
    18  
    19  package initializer_test
    20  
    21  import (
    22  	"path/filepath"
    23  
    24  	v1 "github.com/IBM-Blockchain/fabric-operator/pkg/apis/ca/v1"
    25  	initializer "github.com/IBM-Blockchain/fabric-operator/pkg/initializer/ca"
    26  	"github.com/IBM-Blockchain/fabric-operator/pkg/initializer/ca/config"
    27  	"github.com/IBM-Blockchain/fabric-operator/pkg/initializer/ca/mocks"
    28  	"github.com/IBM-Blockchain/fabric-operator/pkg/util/pointer"
    29  	. "github.com/onsi/ginkgo/v2"
    30  	. "github.com/onsi/gomega"
    31  	"github.com/pkg/errors"
    32  )
    33  
    34  var _ = Describe("IBPCA", func() {
    35  	Context("reading file", func() {
    36  		It("fails load configuration file that doesn't exist", func() {
    37  			_, err := initializer.LoadConfigFromFile("notexist.yaml")
    38  			Expect(err).To(HaveOccurred())
    39  			Expect(err.Error()).To(ContainSubstring("no such file or directory"))
    40  		})
    41  
    42  		It("loads from ca configuration file", func() {
    43  			cfg, err := initializer.LoadConfigFromFile("../../../defaultconfig/ca/ca.yaml")
    44  			Expect(err).NotTo(HaveOccurred())
    45  			Expect(cfg).NotTo(BeNil())
    46  		})
    47  	})
    48  
    49  	Context("ca initializion", func() {
    50  		var (
    51  			ca            *initializer.CA
    52  			defaultConfig *mocks.CAConfig
    53  		)
    54  
    55  		BeforeEach(func() {
    56  			cfg := &config.Config{
    57  				HomeDir:   "ca_test",
    58  				MountPath: "/mount",
    59  				ServerConfig: &v1.ServerConfig{
    60  					CAConfig: v1.CAConfig{
    61  						CSP: &v1.BCCSP{
    62  							ProviderName: "PKCS11",
    63  							PKCS11: &v1.PKCS11Opts{
    64  								Pin:   "1234",
    65  								Label: "root",
    66  							},
    67  						},
    68  						CSR: v1.CSRInfo{
    69  							CN: "ca",
    70  						},
    71  					},
    72  				},
    73  			}
    74  
    75  			defaultConfig = &mocks.CAConfig{}
    76  			defaultConfig.GetServerConfigReturns(cfg.ServerConfig)
    77  			defaultConfig.GetHomeDirReturns(cfg.HomeDir)
    78  
    79  			ca = initializer.NewCA(defaultConfig, config.EnrollmentCA, "/tmp", true, "ca_test")
    80  		})
    81  
    82  		It("sets default values", func() {
    83  			err := ca.OverrideServerConfig(nil)
    84  			Expect(err).NotTo(HaveOccurred())
    85  
    86  			By("enabling removal of identities and affiliations", func() {
    87  				Expect(*defaultConfig.GetServerConfig().CAConfig.Cfg.Identities.AllowRemove).To(Equal(true))
    88  				Expect(*defaultConfig.GetServerConfig().CAConfig.Cfg.Affiliations.AllowRemove).To(Equal(true))
    89  			})
    90  			By("enabling ignore cert expiry for re-enroll", func() {
    91  				Expect(*defaultConfig.GetServerConfig().CAConfig.CA.ReenrollIgnoreCertExpiry).To(Equal(true))
    92  			})
    93  		})
    94  
    95  		It("does not crash if CSP is nil in override config", func() {
    96  			override := &v1.ServerConfig{
    97  				CAConfig: v1.CAConfig{
    98  					CSP: nil,
    99  				},
   100  			}
   101  
   102  			err := ca.OverrideServerConfig(override)
   103  			Expect(err).NotTo(HaveOccurred())
   104  
   105  			By("setting in defaults when using pkcs11", func() {
   106  				Expect(defaultConfig.GetServerConfig().CAConfig.CSP).To(Equal(ca.GetServerConfig().CAConfig.CSP))
   107  				Expect(defaultConfig.GetServerConfig().CAConfig.CSR.CN).To(Equal("ca_test"))
   108  			})
   109  		})
   110  
   111  		It("overrides config", func() {
   112  			override := &v1.ServerConfig{
   113  				CAConfig: v1.CAConfig{
   114  					CSP: &v1.BCCSP{
   115  						ProviderName: "PKCS11",
   116  					},
   117  				},
   118  			}
   119  			defaultConfig.UsingPKCS11Returns(true)
   120  
   121  			err := ca.OverrideServerConfig(override)
   122  			Expect(err).NotTo(HaveOccurred())
   123  
   124  			By("setting in defaults when using pkcs11", func() {
   125  				Expect(defaultConfig.GetServerConfig().CAConfig.CSP.PKCS11.Library).To(Equal("/usr/local/lib/libpkcs11-proxy.so"))
   126  				Expect(defaultConfig.GetServerConfig().CAConfig.CSP.PKCS11.FileKeyStore.KeyStorePath).To(Equal("msp/keystore"))
   127  				Expect(defaultConfig.GetServerConfig().CAConfig.CSP.PKCS11.HashFamily).To(Equal("SHA2"))
   128  				Expect(defaultConfig.GetServerConfig().CAConfig.CSP.PKCS11.SecLevel).To(Equal(256))
   129  				Expect(defaultConfig.GetServerConfig().CAConfig.CSR.CN).To(Equal("ca_test"))
   130  			})
   131  		})
   132  
   133  		It("successfully completes initializing intermediate ca", func() {
   134  			override := &v1.ServerConfig{
   135  				CAConfig: v1.CAConfig{
   136  					Intermediate: v1.IntermediateCA{
   137  						ParentServer: v1.ParentServer{
   138  							URL: "127.0.0.1",
   139  						},
   140  					},
   141  				},
   142  			}
   143  
   144  			err := ca.OverrideServerConfig(override)
   145  			Expect(err).NotTo(HaveOccurred())
   146  
   147  			By("setting cn in csr to be empty", func() {
   148  				Expect(defaultConfig.GetServerConfig().CAConfig.CSR.CN).To(Equal(""))
   149  			})
   150  		})
   151  
   152  		It("writes configuration to file", func() {
   153  			err := ca.WriteConfig()
   154  			Expect(err).NotTo(HaveOccurred())
   155  			Expect(filepath.Join(defaultConfig.GetHomeDir(), "fabric-ca-server-config.yaml")).Should(BeAnExistingFile())
   156  
   157  			ca.RemoveHomeDir()
   158  		})
   159  
   160  		Context("run fabric-ca init", func() {
   161  			BeforeEach(func() {
   162  				cfg, err := initializer.LoadConfigFromFile("../../../defaultconfig/ca/ca.yaml")
   163  				Expect(err).NotTo(HaveOccurred())
   164  				defaultConfig.GetServerConfigReturns(cfg)
   165  
   166  				err = ca.WriteConfig()
   167  				Expect(err).NotTo(HaveOccurred())
   168  			})
   169  
   170  			It("successfully completes Initializing ca", func() {
   171  				err := ca.Init()
   172  				Expect(err).NotTo(HaveOccurred())
   173  
   174  				By("setting ca files property to point to tls ca config file", func() {
   175  					Expect(defaultConfig.GetServerConfig().CAfiles).To(Equal([]string{"/data/tlsca/fabric-ca-server-config.yaml"}))
   176  				})
   177  
   178  				By("setting cert/key file to generate location", func() {
   179  					Expect(defaultConfig.GetServerConfig().CA.Certfile).To(ContainSubstring(filepath.Join(ca.Config.GetHomeDir(), "ca-cert.pem")))
   180  					Expect(defaultConfig.GetServerConfig().CA.Keyfile).To(ContainSubstring(filepath.Join(ca.Config.GetHomeDir(), "ca-key.pem")))
   181  				})
   182  
   183  			})
   184  
   185  			AfterEach(func() {
   186  				err := ca.RemoveHomeDir()
   187  				Expect(err).NotTo(HaveOccurred())
   188  			})
   189  		})
   190  
   191  		Context("viper unmarshal", func() {
   192  			It("returns an error if fails to find file", func() {
   193  				_, err := ca.ViperUnmarshal("../../../defaultconfig/ca/foo.yaml")
   194  				Expect(err).To(HaveOccurred())
   195  			})
   196  
   197  			It("successfully unmarshals", func() {
   198  				cfg, err := ca.ViperUnmarshal("../../../defaultconfig/ca/tlsca.yaml")
   199  				Expect(err).NotTo(HaveOccurred())
   200  				Expect(cfg).NotTo(BeNil())
   201  			})
   202  		})
   203  
   204  		Context("parse enrollment ca crypto", func() {
   205  			BeforeEach(func() {
   206  				defaultConfig.GetServerConfig().TLS = v1.ServerTLSConfig{
   207  					Enabled:  pointer.True(),
   208  					CertFile: "../../../testdata/tls/tls.crt",
   209  					KeyFile:  "../../../testdata/tls/tls.key",
   210  				}
   211  
   212  				defaultConfig.GetServerConfig().Operations = v1.Options{
   213  					TLS: v1.TLS{
   214  						Enabled: pointer.True(),
   215  					},
   216  				}
   217  			})
   218  
   219  			It("returns an error if TLS cert and key not provided", func() {
   220  				defaultConfig.GetServerConfig().TLS.CertFile = ""
   221  				defaultConfig.GetServerConfig().TLS.KeyFile = ""
   222  
   223  				_, err := ca.ParseEnrollmentCACrypto()
   224  				Expect(err).To(HaveOccurred())
   225  				Expect(err.Error()).To(Equal("no TLS cert and key file provided"))
   226  			})
   227  
   228  			It("returns an error is parsing ca blocks fails", func() {
   229  				msg := "failed ca parse"
   230  				defaultConfig.ParseCABlockReturns(nil, errors.New(msg))
   231  
   232  				_, err := ca.ParseEnrollmentCACrypto()
   233  				Expect(err).To(HaveOccurred())
   234  				Expect(err.Error()).To(Equal("failed to parse ca block: " + msg))
   235  			})
   236  
   237  			It("returns an error is parsing TLS blocks fails", func() {
   238  				msg := "failed tls parse"
   239  				defaultConfig.ParseTLSBlockReturns(nil, errors.New(msg))
   240  
   241  				_, err := ca.ParseEnrollmentCACrypto()
   242  				Expect(err).To(HaveOccurred())
   243  				Expect(err.Error()).To(Equal("failed to parse tls block: " + msg))
   244  			})
   245  
   246  			It("returns an error is parsing DB blocks fails", func() {
   247  				msg := "failed db parse"
   248  				defaultConfig.ParseDBBlockReturns(nil, errors.New(msg))
   249  
   250  				_, err := ca.ParseEnrollmentCACrypto()
   251  				Expect(err).To(HaveOccurred())
   252  				Expect(err.Error()).To(Equal("failed to parse db block: " + msg))
   253  			})
   254  
   255  			It("returns an error is parsing operations blocks fails", func() {
   256  				msg := "failed operations parse"
   257  				defaultConfig.ParseOperationsBlockReturns(nil, errors.New(msg))
   258  
   259  				_, err := ca.ParseEnrollmentCACrypto()
   260  				Expect(err).To(HaveOccurred())
   261  				Expect(err.Error()).To(Equal("failed to parse operations block: " + msg))
   262  			})
   263  
   264  			It("returns an error is parsing intermediate blocks fails", func() {
   265  				msg := "failed operations parse"
   266  				defaultConfig.ParseIntermediateBlockReturns(nil, errors.New(msg))
   267  
   268  				_, err := ca.ParseEnrollmentCACrypto()
   269  				Expect(err).To(HaveOccurred())
   270  				Expect(err.Error()).To(Equal("failed to parse intermediate block: " + msg))
   271  			})
   272  
   273  			It("sets the operations TLS path to be equal to server's TLS path", func() {
   274  				_, err := ca.ParseEnrollmentCACrypto()
   275  				Expect(err).NotTo(HaveOccurred())
   276  
   277  				Expect(defaultConfig.GetServerConfig().Operations.TLS.CertFile).To(ContainSubstring("tls/tls.crt"))
   278  				Expect(defaultConfig.GetServerConfig().Operations.TLS.KeyFile).To(ContainSubstring("tls/tls.key"))
   279  			})
   280  		})
   281  
   282  		Context("parse TLS ca crypto", func() {
   283  			It("returns an error is parsing ca blocks fails", func() {
   284  				msg := "failed ca parse"
   285  				defaultConfig.ParseCABlockReturns(nil, errors.New(msg))
   286  
   287  				_, err := ca.ParseTLSCACrypto()
   288  				Expect(err).To(HaveOccurred())
   289  				Expect(err.Error()).To(Equal("failed to parse ca block: " + msg))
   290  			})
   291  
   292  			It("parses ca blocks fails", func() {
   293  				_, err := ca.ParseTLSCACrypto()
   294  				Expect(err).NotTo(HaveOccurred())
   295  			})
   296  		})
   297  	})
   298  })