Skip to content

Commit

Permalink
Merge "[FAB-7223] Wrap CRL PEM file at 64 characters"
Browse files Browse the repository at this point in the history
  • Loading branch information
Keith Smith authored and Gerrit Code Review committed Dec 19, 2017
2 parents a82b326 + 52ea881 commit a6b0a78
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 79 deletions.
7 changes: 4 additions & 3 deletions api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ type RevocationRequest struct {
type RevocationResponse struct {
// RevokedCerts is an array of certificates that were revoked
RevokedCerts []RevokedCert
// CRL is base64 encoded DER bytes of a CRL that contains all unexpired revoked certificates
CRL string
// CRL is PEM-encoded certificate revocation list (CRL) that contains all unexpired revoked certificates
CRL []byte
}

// RevokedCert represents a revoked certificate
Expand Down Expand Up @@ -189,7 +189,8 @@ type GenCRLRequest struct {

// GenCRLResponse represents a response to get CRL
type GenCRLResponse struct {
CRL string
// CRL is PEM-encoded certificate revocation list (CRL) that contains requested unexpired revoked certificates
CRL []byte
}

// AddIdentityRequest represents the request to add a new identity to the
Expand Down
9 changes: 2 additions & 7 deletions cmd/fabric-ca-client/gencrl.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ limitations under the License.
package main

import (
"fmt"
"os"
"path"
"path/filepath"
Expand All @@ -32,10 +31,6 @@ const (
crlsFolder = "crls"
// crlFile is the name of the file used to the generate CRL
crlFile = "crl.pem"
// crlPemHeader is the header of a X509 CRL
crlPemHeader = "-----BEGIN X509 CRL-----\n"
// crlPemFooter is the footer of a X509 CRL
crlPemFooter = "\n-----END X509 CRL-----\n"
)

func (c *ClientCmd) newGenCRLCommand() *cobra.Command {
Expand Down Expand Up @@ -134,7 +129,7 @@ func (c *ClientCmd) runGenCRL() error {
}

// Store the CRL
func storeCRL(config *lib.ClientConfig, crl string) error {
func storeCRL(config *lib.ClientConfig, crl []byte) error {
dirName := path.Join(config.MSPDir, crlsFolder)
if _, err := os.Stat(dirName); os.IsNotExist(err) {
mkdirErr := os.MkdirAll(dirName, os.ModeDir|0755)
Expand All @@ -143,7 +138,7 @@ func storeCRL(config *lib.ClientConfig, crl string) error {
}
}
fileName := path.Join(dirName, crlFile)
err := util.WriteFile(fileName, []byte(fmt.Sprintf("%s%s%s", crlPemHeader, crl, crlPemFooter)), 0644)
err := util.WriteFile(fileName, crl, 0644)
if err != nil {
return errors.Wrapf(err, "Failed to write CRL to the file %s", fileName)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/fabric-ca-client/revoke.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func (c *ClientCmd) runRevoke(cmd *cobra.Command) error {
}
log.Infof("Sucessfully revoked certificates: %+v", result.RevokedCerts)

if req.GenCRL && result.CRL != "" {
if req.GenCRL {
return storeCRL(c.clientCfg, result.CRL)
}
return nil
Expand Down
16 changes: 12 additions & 4 deletions lib/identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,17 @@ func (i *Identity) Revoke(req *api.RevocationRequest) (*api.RevocationResponse,
if err != nil {
return nil, err
}
var result api.RevocationResponse
var result revocationResponseNet
err = i.Post("revoke", reqBody, &result)
if err != nil {
return nil, err
}
log.Debugf("Successfully revoked certificates: %+v", req)
return &result, nil
crl, err := util.B64Decode(result.CRL)
if err != nil {
return nil, err
}
return &api.RevocationResponse{RevokedCerts: result.RevokedCerts, CRL: crl}, nil
}

// RevokeSelf revokes the current identity and all certificates
Expand All @@ -191,13 +195,17 @@ func (i *Identity) GenCRL(req *api.GenCRLRequest) (*api.GenCRLResponse, error) {
if err != nil {
return nil, err
}
var result api.GenCRLResponse
var result genCRLResponseNet
err = i.Post("gencrl", reqBody, &result)
if err != nil {
return nil, err
}
log.Debugf("Successfully generated CRL: %+v", req)
return &result, nil
crl, err := util.B64Decode(result.CRL)
if err != nil {
return nil, err
}
return &api.GenCRLResponse{CRL: crl}, nil
}

// GetIdentity returns information about the requested identity
Expand Down
33 changes: 23 additions & 10 deletions lib/servergencrl.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package lib
import (
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"fmt"
"io/ioutil"
"math/big"
Expand All @@ -31,9 +32,14 @@ import (
"github.com/pkg/errors"
)

// The response to the GET /info request
const (
crlPemType = "X509 CRL"
)

// The response to the POST /gencrl request
type genCRLResponseNet struct {
CRL []byte
// Base64 encoding of PEM-encoded CRL
CRL string
}

func newGenCRLEndpoint(s *Server) *serverEndpoint {
Expand Down Expand Up @@ -80,7 +86,7 @@ func genCRLHandler(ctx *serverRequestContext) (interface{}, error) {
}
log.Debugf("Successfully generated CRL")

resp := &genCRLResponseNet{CRL: crl}
resp := &genCRLResponseNet{CRL: util.B64Encode(crl)}
return resp, nil
}

Expand All @@ -92,32 +98,38 @@ func genCRL(ca *CA, req api.GenCRLRequest) ([]byte, error) {
revokedBefore = time.Now().UTC()
}
if req.RevokedAfter.After(revokedBefore) {
return nil, newHTTPErr(400, ErrInvalidRevokedAfter, "Invalid 'revokedafter' value. It must not be a timestamp greater than 'revokedbefore'")
return nil, newHTTPErr(400, ErrInvalidRevokedAfter,
"Invalid 'revokedafter' value. It must not be a timestamp greater than 'revokedbefore'")
}

if req.ExpireAfter.After(req.ExpireBefore) {
return nil, newHTTPErr(400, ErrInvalidExpiredAfter, "Invalid 'expireafter' value. It must not be a timestamp greater than 'expirebefore'")
return nil, newHTTPErr(400, ErrInvalidExpiredAfter,
"Invalid 'expireafter' value. It must not be a timestamp greater than 'expirebefore'")
}

// Get revoked certificates from the database
certs, err := ca.certDBAccessor.GetRevokedCertificates(req.ExpireAfter, req.ExpireBefore, req.RevokedAfter, revokedBefore)
if err != nil {
return nil, newHTTPErr(500, ErrRevokedCertsFromDB, "Failed to get revoked certificates from the database: %s", err)
return nil, newHTTPErr(500, ErrRevokedCertsFromDB,
"Failed to get revoked certificates from the database: %s", err)
}

caCert, err := getCACert(ca)
if err != nil {
return nil, newHTTPErr(500, ErrGetCACert, "Failed to get certficate for the CA '%s': %s", ca.HomeDir, err)
return nil, newHTTPErr(500, ErrGetCACert,
"Failed to get certficate for the CA '%s': %s", ca.HomeDir, err)
}

if !canSignCRL(caCert) {
return nil, newHTTPErr(500, ErrNoCrlSignAuth, "The CA does not have authority to generate a CRL. Its certificate does not have 'crl sign' key usage")
return nil, newHTTPErr(500, ErrNoCrlSignAuth,
"The CA does not have authority to generate a CRL. Its certificate does not have 'crl sign' key usage")
}

// Get the signer for the CA
_, signer, err := util.GetSignerFromCert(caCert, ca.csp)
if err != nil {
return nil, newHTTPErr(500, ErrGetCASigner, "Failed to get signer for the CA '%s': %s", ca.HomeDir, err)
return nil, newHTTPErr(500, ErrGetCASigner,
"Failed to get signer for the CA '%s': %s", ca.HomeDir, err)
}

expiry := time.Now().UTC().Add(ca.Config.CRL.Expiry)
Expand All @@ -138,7 +150,8 @@ func genCRL(ca *CA, req api.GenCRLRequest) ([]byte, error) {
if err != nil {
return nil, newHTTPErr(500, ErrGenCRL, "Failed to generate the CRL for the CA '%s': %s", ca.HomeDir, err)
}
return crl, nil
blk := &pem.Block{Bytes: crl, Type: crlPemType}
return pem.EncodeToMemory(blk), nil
}

func getCACert(ca *CA) (*x509.Certificate, error) {
Expand Down
5 changes: 2 additions & 3 deletions lib/serverrevoke.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import (

type revocationResponseNet struct {
RevokedCerts []api.RevokedCert
CRL []byte
CRL string
}

func newRevokeEndpoint(s *Server) *serverEndpoint {
Expand Down Expand Up @@ -158,8 +158,7 @@ func revokeHandler(ctx *serverRequestContext) (interface{}, error) {
if err != nil {
return nil, err
}
result.CRL = crl
result.CRL = util.B64Encode(crl)
}

return result, nil
}
Loading

0 comments on commit a6b0a78

Please sign in to comment.