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 }