github.com/silveraid/fabric-ca@v1.1.0-preview.0.20180127000700-71974f53ab08/cmd/fabric-ca-client/gencrl.go (about) 1 /* 2 Copyright IBM Corp. 2017 All Rights Reserved. 3 Licensed under the Apache License, Version 2.0 (the "License"); 4 you may not use this file except in compliance with the License. 5 You may obtain a copy of the License at 6 http://www.apache.org/licenses/LICENSE-2.0 7 Unless required by applicable law or agreed to in writing, software 8 distributed under the License is distributed on an "AS IS" BASIS, 9 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 See the License for the specific language governing permissions and 11 limitations under the License. 12 */ 13 package main 14 15 import ( 16 "os" 17 "path" 18 "path/filepath" 19 "time" 20 21 "github.com/cloudflare/cfssl/log" 22 "github.com/hyperledger/fabric-ca/api" 23 "github.com/hyperledger/fabric-ca/lib" 24 "github.com/hyperledger/fabric-ca/util" 25 "github.com/pkg/errors" 26 "github.com/spf13/cobra" 27 ) 28 29 const ( 30 // crlsFolder is the MSP folder name where generate CRL will be stored 31 crlsFolder = "crls" 32 // crlFile is the name of the file used to the generate CRL 33 crlFile = "crl.pem" 34 ) 35 36 func (c *ClientCmd) newGenCRLCommand() *cobra.Command { 37 var genCrlCmd = &cobra.Command{ 38 Use: "gencrl", 39 Short: "Generate a CRL", 40 Long: "Generate a Certificate Revocation List", 41 // PreRunE block for this command will load client configuration 42 // before running the command 43 PreRunE: func(cmd *cobra.Command, args []string) error { 44 if len(args) > 0 { 45 return errors.Errorf(extraArgsError, args, cmd.UsageString()) 46 } 47 err := c.configInit() 48 if err != nil { 49 return err 50 } 51 log.Debugf("Client configuration settings: %+v", c.clientCfg) 52 return nil 53 }, 54 RunE: func(cmd *cobra.Command, args []string) error { 55 err := c.runGenCRL() 56 if err != nil { 57 return err 58 } 59 return nil 60 }, 61 } 62 util.RegisterFlags(c.myViper, genCrlCmd.Flags(), &c.crlParams, nil) 63 return genCrlCmd 64 } 65 66 // The client register main logic 67 func (c *ClientCmd) runGenCRL() error { 68 log.Debug("Entered runGenCRL") 69 client := lib.Client{ 70 HomeDir: filepath.Dir(c.cfgFileName), 71 Config: c.clientCfg, 72 } 73 id, err := client.LoadMyIdentity() 74 if err != nil { 75 return err 76 } 77 var revokedAfter, revokedBefore time.Time 78 if c.crlParams.RevokedAfter != "" { 79 revokedAfter, err = time.Parse(time.RFC3339, c.crlParams.RevokedAfter) 80 if err != nil { 81 return errors.Wrap(err, "Invalid 'revokedafter' value") 82 } 83 } 84 if c.crlParams.RevokedBefore != "" { 85 revokedBefore, err = time.Parse(time.RFC3339, c.crlParams.RevokedBefore) 86 if err != nil { 87 return errors.Wrap(err, "Invalid 'revokedbefore' value") 88 } 89 } 90 if !revokedBefore.IsZero() && revokedAfter.After(revokedBefore) { 91 return errors.Errorf("Invalid revokedafter value '%s'. It must not be a timestamp greater than revokedbefore value '%s'", 92 c.crlParams.RevokedAfter, c.crlParams.RevokedBefore) 93 } 94 95 var expireAfter, expireBefore time.Time 96 if c.crlParams.ExpireAfter != "" { 97 expireAfter, err = time.Parse(time.RFC3339, c.crlParams.ExpireAfter) 98 if err != nil { 99 return errors.Wrap(err, "Invalid 'expireafter' value") 100 } 101 } 102 if c.crlParams.ExpireBefore != "" { 103 expireBefore, err = time.Parse(time.RFC3339, c.crlParams.ExpireBefore) 104 if err != nil { 105 return errors.Wrap(err, "Invalid 'expirebefore' value") 106 } 107 } 108 if !expireBefore.IsZero() && expireAfter.After(expireBefore) { 109 return errors.Errorf("Invalid expireafter value '%s'. It must not be a timestamp greater than expirebefore value '%s'", 110 c.crlParams.ExpireAfter, c.crlParams.ExpireBefore) 111 } 112 req := &api.GenCRLRequest{ 113 CAName: c.clientCfg.CAName, 114 RevokedAfter: revokedAfter, 115 RevokedBefore: revokedBefore, 116 ExpireAfter: expireAfter, 117 ExpireBefore: expireBefore, 118 } 119 resp, err := id.GenCRL(req) 120 if err != nil { 121 return err 122 } 123 log.Info("Successfully generated the CRL") 124 err = storeCRL(c.clientCfg, resp.CRL) 125 if err != nil { 126 return err 127 } 128 return nil 129 } 130 131 // Store the CRL 132 func storeCRL(config *lib.ClientConfig, crl []byte) error { 133 dirName := path.Join(config.MSPDir, crlsFolder) 134 if _, err := os.Stat(dirName); os.IsNotExist(err) { 135 mkdirErr := os.MkdirAll(dirName, os.ModeDir|0755) 136 if mkdirErr != nil { 137 return errors.Wrapf(mkdirErr, "Failed to create directory %s", dirName) 138 } 139 } 140 fileName := path.Join(dirName, crlFile) 141 err := util.WriteFile(fileName, crl, 0644) 142 if err != nil { 143 return errors.Wrapf(err, "Failed to write CRL to the file %s", fileName) 144 } 145 log.Info("Successfully stored the CRL in the file %s", fileName) 146 return nil 147 }