gitee.com/zhaochuninhefei/fabric-ca-gm@v0.0.2/lib/serverenroll_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package lib
     8  
     9  import (
    10  	"os"
    11  	"testing"
    12  	"time"
    13  
    14  	"gitee.com/zhaochuninhefei/cfssl-gm/signer"
    15  	"gitee.com/zhaochuninhefei/fabric-ca-gm/internal/pkg/api"
    16  	"gitee.com/zhaochuninhefei/fabric-ca-gm/internal/pkg/util"
    17  	dbuser "gitee.com/zhaochuninhefei/fabric-ca-gm/lib/server/user"
    18  	"github.com/stretchr/testify/assert"
    19  )
    20  
    21  func TestStateUpdate(t *testing.T) {
    22  	cleanTestSlateSE(t)
    23  	defer cleanTestSlateSE(t)
    24  
    25  	var err error
    26  	srv := TestGetRootServer(t)
    27  
    28  	err = srv.Start()
    29  	assert.NoError(t, err, "Failed to start server")
    30  
    31  	client := getTestClient(rootPort)
    32  	_, err = client.Enroll(&api.EnrollmentRequest{
    33  		Name:   "admin",
    34  		Secret: "adminpw",
    35  	})
    36  	assert.NoError(t, err, "Failed to enroll 'admin' user")
    37  
    38  	registry := srv.CA.DBAccessor()
    39  	userInfo, err := registry.GetUser("admin", nil)
    40  	assert.NoError(t, err, "Failed to get user 'admin' from database")
    41  	// User state should have gotten updated to 1 after a successful enrollment
    42  	if userInfo.(*dbuser.Impl).State != 1 {
    43  		t.Error("Incorrect state set for user")
    44  	}
    45  
    46  	// Send bad CSR to cause the enroll to fail but the login to succeed
    47  	reqNet := &api.EnrollmentRequestNet{}
    48  	reqNet.SignRequest.Request = "badcsr"
    49  	body, err := util.Marshal(reqNet, "SignRequest")
    50  	assert.NoError(t, err, "Failed to marshal enroll request")
    51  
    52  	// Send the CSR to the fabric-ca server with basic auth header
    53  	post, err := client.newPost("enroll", body)
    54  	assert.NoError(t, err, "Failed to create post request")
    55  	post.SetBasicAuth("admin", "adminpw")
    56  	err = client.SendReq(post, nil)
    57  	if assert.Error(t, err, "Should have failed due to bad csr") {
    58  		assert.Contains(t, err.Error(), "CSR Decode failed")
    59  	}
    60  
    61  	// State should not have gotten updated because the enrollment failed
    62  	userInfo, err = registry.GetUser("admin", nil)
    63  	assert.NoError(t, err, "Failed to get user 'admin' from database")
    64  	if userInfo.(*dbuser.Impl).State != 1 {
    65  		t.Error("Incorrect state set for user")
    66  	}
    67  
    68  	err = srv.Stop()
    69  	assert.NoError(t, err, "Failed to stop server")
    70  
    71  }
    72  
    73  func cleanTestSlateSE(t *testing.T) {
    74  	err := os.RemoveAll(rootDir)
    75  	if err != nil {
    76  		t.Errorf("RemoveAll failed: %s", err)
    77  	}
    78  	err = os.RemoveAll("../testdata/msp")
    79  	if err != nil {
    80  		t.Errorf("RemoveAll failed: %s", err)
    81  	}
    82  }
    83  
    84  func TestPasswordLimit(t *testing.T) {
    85  	cleanTestSlateSE(t)
    86  	defer cleanTestSlateSE(t)
    87  
    88  	passLimit := 3
    89  
    90  	srv := TestGetRootServer(t)
    91  	srv.CA.Config.Cfg.Identities.PasswordAttempts = passLimit
    92  	err := srv.Start()
    93  	util.FatalError(t, err, "Failed to start server")
    94  	defer srv.Stop()
    95  
    96  	client := getTestClient(rootPort)
    97  	enrollResp, err := client.Enroll(&api.EnrollmentRequest{
    98  		Name:   "admin",
    99  		Secret: "adminpw",
   100  	})
   101  	util.FatalError(t, err, "Failed to enroll 'admin' user")
   102  	admin := enrollResp.Identity
   103  
   104  	_, err = admin.Register(&api.RegistrationRequest{
   105  		Name:   "user1",
   106  		Secret: "user1pw",
   107  	})
   108  	util.FatalError(t, err, "Failed to register 'user1' user")
   109  
   110  	// Reach maximum incorrect password limit
   111  	for i := 0; i < passLimit; i++ {
   112  		_, err = client.Enroll(&api.EnrollmentRequest{
   113  			Name:   "user1",
   114  			Secret: "badpass",
   115  		})
   116  		assert.Error(t, err, "Enroll for user 'user1' should fail due to bad password")
   117  	}
   118  	_, err = client.Enroll(&api.EnrollmentRequest{
   119  		Name:   "user1",
   120  		Secret: "badpass",
   121  	})
   122  	util.ErrorContains(t, err, "73", "Should fail, incorrect password limit reached")
   123  
   124  	// Admin modifying identity, confirm that just modifying identity does not reset attempt
   125  	// count. Incorrect password attempt count should only be reset to zero, if password
   126  	// is modified.
   127  	modReq := &api.ModifyIdentityRequest{
   128  		ID: "user1",
   129  	}
   130  
   131  	modReq.Type = "client"
   132  	_, err = admin.ModifyIdentity(modReq)
   133  	assert.NoError(t, err, "Failed to modify identity")
   134  
   135  	_, err = client.Enroll(&api.EnrollmentRequest{
   136  		Name:   "user1",
   137  		Secret: "user1pw",
   138  	})
   139  	assert.Error(t, err, "Should failed to enroll")
   140  
   141  	// Admin reset password
   142  	modReq.Secret = "newPass"
   143  	_, err = admin.ModifyIdentity(modReq)
   144  	assert.NoError(t, err, "Failed to modify identity")
   145  
   146  	_, err = client.Enroll(&api.EnrollmentRequest{
   147  		Name:   "user1",
   148  		Secret: "newPass",
   149  	})
   150  	assert.NoError(t, err, "Failed to enroll using new password after admin reset password")
   151  
   152  	// Test that if password is entered correctly before reaching incorrect password limit,
   153  	// the incorrect password count is reset back to 0
   154  	_, err = client.Enroll(&api.EnrollmentRequest{
   155  		Name:   "user1",
   156  		Secret: "badPass",
   157  	})
   158  	assert.Error(t, err, "Enroll for user 'user1' should fail due to bad password")
   159  
   160  	registry := srv.CA.DBAccessor()
   161  	user1, err := registry.GetUser("user1", nil)
   162  	util.FatalError(t, err, "Failed to get 'user1' from database")
   163  	assert.Equal(t, 1, user1.GetFailedLoginAttempts())
   164  
   165  	_, err = client.Enroll(&api.EnrollmentRequest{
   166  		Name:   "user1",
   167  		Secret: "newPass",
   168  	})
   169  	assert.NoError(t, err, "Failed to enroll user with correct password")
   170  
   171  	user1, err = registry.GetUser("user1", nil)
   172  	util.FatalError(t, err, "Failed to get 'user1' from database")
   173  	assert.Equal(t, 0, user1.GetFailedLoginAttempts())
   174  }
   175  
   176  func TestCertificateExpiration(t *testing.T) {
   177  	cleanTestSlateSE(t)
   178  	defer cleanTestSlateSE(t)
   179  
   180  	srv := TestGetRootServer(t)
   181  	err := srv.Start()
   182  	util.FatalError(t, err, "Failed to start server")
   183  	defer srv.Stop()
   184  
   185  	caCertPem, _ := srv.CA.getCACert()
   186  	caCert, _ := util.GetX509CertificateFromPEM(caCertPem)
   187  
   188  	client := getTestClient(rootPort)
   189  
   190  	csrPEM, _, err := client.GenCSR(&api.CSRInfo{CN: "admin"}, "admin")
   191  	assert.NoError(t, err, "Failed to generate CSR")
   192  
   193  	reqNet := &api.EnrollmentRequestNet{
   194  		SignRequest: signer.SignRequest{
   195  			Request: string(csrPEM),
   196  			// requesting certificate with validity time wider then CA cert
   197  			NotBefore: caCert.NotBefore.Add(-1 * time.Hour),
   198  			NotAfter:  caCert.NotAfter.Add(24 * time.Hour),
   199  		},
   200  	}
   201  
   202  	body, err := util.Marshal(reqNet, "SignRequest")
   203  	assert.NoError(t, err, "Failed to marshal enroll request")
   204  
   205  	// Send the CSR to the fabric-ca server with basic auth header
   206  	post, err := client.newPost("enroll", body)
   207  	assert.NoError(t, err, "Failed to create post request")
   208  	post.SetBasicAuth("admin", "adminpw")
   209  
   210  	var result api.EnrollmentResponseNet
   211  	err = client.SendReq(post, &result)
   212  	assert.NoError(t, err, "Failed to enroll")
   213  
   214  	// verify response
   215  	certBytes, err := util.B64Decode(result.Cert)
   216  	assert.NoError(t, err, "Failed to convert certificate")
   217  	userCert, err := util.GetX509CertificateFromPEM(certBytes)
   218  	assert.NoError(t, err, "Failed to extract certificate from enroll response")
   219  
   220  	// certificate validity is in range of CA cert validity
   221  	assertValidityInRange(t, userCert.NotBefore, userCert.NotAfter, caCert.NotBefore, caCert.NotAfter)
   222  
   223  	// ensure that CA issue a certificate with starting time as early as possible
   224  	assert.True(t, userCert.NotBefore.Equal(caCert.NotBefore), "certificate starting time should be as early as possible")
   225  }
   226  
   227  func assertValidityInRange(t assert.TestingT, certNotBefore time.Time, certNotAfter time.Time, caNotBefore time.Time, caNotAfter time.Time) {
   228  	// caCertNotBefore <= certNotBefore < certNotAfter <= caCertNotAfter
   229  
   230  	assert.True(t, certNotBefore.Before(certNotAfter), "certificate without valid time NotBefore is not before NotAfter")
   231  
   232  	assert.False(t, certNotBefore.Before(caNotBefore),
   233  		"certificate NotBefore %v is before CA cert NotBefore %v", certNotBefore, caNotBefore)
   234  	assert.False(t, certNotAfter.After(caNotAfter),
   235  		"user certificate NotAfter %v is after CA cert NotAfter %v", certNotAfter, caNotAfter)
   236  }