diff --git a/attrmgr/attrmgr.go b/attrmgr/attrmgr.go deleted file mode 100644 index 3e4c24bdc..000000000 --- a/attrmgr/attrmgr.go +++ /dev/null @@ -1,193 +0,0 @@ -/* -Copyright IBM Corp. 2017 All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* - * The attrmgr package contains utilities for managing attributes. - * Attributes are added to an X509 certificate as an extension. - */ - -package attrmgr - -import ( - "crypto/x509" - "crypto/x509/pkix" - "encoding/asn1" - "encoding/json" - - "github.com/pkg/errors" -) - -var ( - // AttrOID is the ASN.1 object identifier for an attribute extension in an - // X509 certificate - AttrOID = asn1.ObjectIdentifier{1, 2, 3, 4, 5, 6, 7, 8, 1} - // AttrOIDString is the string version of AttrOID - AttrOIDString = "1.2.3.4.5.6.7.8.1" -) - -// Attribute is a name/value pair -type Attribute interface { - // GetName returns the name of the attribute - GetName() string - // GetValue returns the value of the attribute - GetValue() string -} - -// AttributeRequest is a request for an attribute -type AttributeRequest interface { - // GetName returns the name of an attribute - GetName() string - // IsRequired returns true if the attribute is required - IsRequired() bool -} - -// New constructs an attribute manager -func New() *Mgr { return &Mgr{} } - -// Mgr is the attribute manager and is the main object for this package -type Mgr struct{} - -// ProcessAttributeRequestsForCert add attributes to an X509 certificate, given -// attribute requests and attributes. -func (mgr *Mgr) ProcessAttributeRequestsForCert(requests []AttributeRequest, attributes []Attribute, cert *x509.Certificate) error { - attrs, err := mgr.ProcessAttributeRequests(requests, attributes) - if err != nil { - return err - } - return mgr.AddAttributesToCert(attrs, cert) -} - -// ProcessAttributeRequests takes an array of attribute requests and an identity's attributes -// and returns an Attributes object containing the requested attributes. -func (mgr *Mgr) ProcessAttributeRequests(requests []AttributeRequest, attributes []Attribute) (*Attributes, error) { - attrsMap := map[string]string{} - attrs := &Attributes{Attrs: attrsMap} - missingRequiredAttrs := []string{} - // For each of the attribute requests - for _, req := range requests { - // Get the attribute - name := req.GetName() - attr := getAttrByName(name, attributes) - if attr == nil { - if req.IsRequired() { - // Didn't find attribute and it was required; return error below - missingRequiredAttrs = append(missingRequiredAttrs, name) - } - // Skip attribute requests which aren't required - continue - } - attrsMap[name] = attr.GetValue() - } - if len(missingRequiredAttrs) > 0 { - return nil, errors.Errorf("The following required attributes are missing: %+v", - missingRequiredAttrs) - } - return attrs, nil -} - -// AddAttributesToCert adds public attribute info to an X509 certificate. -func (mgr *Mgr) AddAttributesToCert(attrs *Attributes, cert *x509.Certificate) error { - buf, err := json.Marshal(attrs) - if err != nil { - return errors.Wrap(err, "Failed to marshal attributes") - } - ext := pkix.Extension{ - Id: AttrOID, - Critical: false, - Value: buf, - } - cert.Extensions = append(cert.Extensions, ext) - return nil -} - -// GetAttributesFromCert gets the attributes from a certificate. -func (mgr *Mgr) GetAttributesFromCert(cert *x509.Certificate) (*Attributes, error) { - // Get certificate attributes from the certificate if it exists - buf, err := getAttributesFromCert(cert) - if err != nil { - return nil, err - } - // Unmarshal into attributes object - attrs := &Attributes{} - if buf != nil { - err := json.Unmarshal(buf, attrs) - if err != nil { - return nil, errors.Wrap(err, "Failed to unmarshal attributes from certificate") - } - } - return attrs, nil -} - -// Attributes contains attribute names and values -type Attributes struct { - Attrs map[string]string `json:"attrs"` -} - -// Names returns the names of the attributes -func (a *Attributes) Names() []string { - i := 0 - names := make([]string, len(a.Attrs)) - for name := range a.Attrs { - names[i] = name - i++ - } - return names -} - -// Contains returns true if the named attribute is found -func (a *Attributes) Contains(name string) bool { - _, ok := a.Attrs[name] - return ok -} - -// Value returns an attribute's value -func (a *Attributes) Value(name string) (string, bool, error) { - attr, ok := a.Attrs[name] - return attr, ok, nil -} - -// Get the attribute info from a certificate extension, or return nil if not found -func getAttributesFromCert(cert *x509.Certificate) ([]byte, error) { - for _, ext := range cert.Extensions { - if isAttrOID(ext.Id) { - return ext.Value, nil - } - } - return nil, nil -} - -// Is the object ID equal to the attribute info object ID? -func isAttrOID(oid asn1.ObjectIdentifier) bool { - if len(oid) != len(AttrOID) { - return false - } - for idx, val := range oid { - if val != AttrOID[idx] { - return false - } - } - return true -} - -// Get an attribute from 'attrs' by its name, or nil if not found -func getAttrByName(name string, attrs []Attribute) Attribute { - for _, attr := range attrs { - if attr.GetName() == name { - return attr - } - } - return nil -} diff --git a/attrmgr/attrmgr_test.go b/attrmgr/attrmgr_test.go deleted file mode 100644 index 34f0d32b5..000000000 --- a/attrmgr/attrmgr_test.go +++ /dev/null @@ -1,113 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ -package attrmgr_test - -import ( - "crypto/x509" - "testing" - - "github.com/hyperledger/fabric-ca/attrmgr" - "github.com/stretchr/testify/assert" -) - -// TestAttrs tests attributes -func TestAttrs(t *testing.T) { - mgr := attrmgr.New() - attrs := []attrmgr.Attribute{ - &Attribute{Name: "attr1", Value: "val1"}, - &Attribute{Name: "attr2", Value: "val2"}, - &Attribute{Name: "attr3", Value: "val3"}, - } - reqs := []attrmgr.AttributeRequest{ - &AttributeRequest{Name: "attr1", Require: false}, - &AttributeRequest{Name: "attr2", Require: true}, - &AttributeRequest{Name: "noattr1", Require: false}, - } - cert := &x509.Certificate{} - - // Verify that the certificate has no attributes - at, err := mgr.GetAttributesFromCert(cert) - if err != nil { - t.Fatalf("Failed to GetAttributesFromCert: %s", err) - } - numAttrs := len(at.Names()) - assert.True(t, numAttrs == 0, "expecting 0 attributes but found %d", numAttrs) - - // Add attributes to certificate - err = mgr.ProcessAttributeRequestsForCert(reqs, attrs, cert) - if err != nil { - t.Fatalf("Failed to ProcessAttributeRequestsForCert: %s", err) - } - - // Get attributes from the certificate and verify the count is correct - at, err = mgr.GetAttributesFromCert(cert) - if err != nil { - t.Fatalf("Failed to GetAttributesFromCert: %s", err) - } - numAttrs = len(at.Names()) - assert.True(t, numAttrs == 2, "expecting 2 attributes but found %d", numAttrs) - - // Check individual attributes - checkAttr(t, "attr1", "val1", at) - checkAttr(t, "attr2", "val2", at) - checkAttr(t, "attr3", "", at) - checkAttr(t, "noattr1", "", at) - - // Negative test case: add required attributes which don't exist - reqs = []attrmgr.AttributeRequest{ - &AttributeRequest{Name: "noattr1", Require: true}, - } - err = mgr.ProcessAttributeRequestsForCert(reqs, attrs, cert) - assert.Error(t, err) -} - -func checkAttr(t *testing.T, name, val string, attrs *attrmgr.Attributes) { - v, ok, err := attrs.Value(name) - assert.NoError(t, err) - if val == "" { - assert.False(t, attrs.Contains(name), "contains attribute '%s'", name) - assert.False(t, ok, "attribute '%s' was found", name) - } else { - assert.True(t, attrs.Contains(name), "does not contain attribute '%s'", name) - assert.True(t, ok, "attribute '%s' was not found", name) - assert.True(t, v == val, "incorrect value for '%s'; expected '%s' but found '%s'", name, val, v) - } -} - -type Attribute struct { - Name, Value string -} - -func (a *Attribute) GetName() string { - return a.Name -} - -func (a *Attribute) GetValue() string { - return a.Value -} - -type AttributeRequest struct { - Name string - Require bool -} - -func (ar *AttributeRequest) GetName() string { - return ar.Name -} - -func (ar *AttributeRequest) IsRequired() bool { - return ar.Require -} diff --git a/cmd/fabric-ca-client/main_test.go b/cmd/fabric-ca-client/main_test.go index 230cfef33..38d9b755b 100644 --- a/cmd/fabric-ca-client/main_test.go +++ b/cmd/fabric-ca-client/main_test.go @@ -31,10 +31,10 @@ import ( "testing" "github.com/hyperledger/fabric-ca/api" - "github.com/hyperledger/fabric-ca/attrmgr" "github.com/hyperledger/fabric-ca/lib" "github.com/hyperledger/fabric-ca/lib/dbutil" "github.com/hyperledger/fabric-ca/util" + "github.com/hyperledger/fabric/common/attrmgr" "github.com/stretchr/testify/assert" ) diff --git a/lib/ca.go b/lib/ca.go index 4172b68b4..af7976644 100644 --- a/lib/ca.go +++ b/lib/ca.go @@ -39,7 +39,6 @@ import ( "github.com/cloudflare/cfssl/log" "github.com/cloudflare/cfssl/signer" "github.com/hyperledger/fabric-ca/api" - "github.com/hyperledger/fabric-ca/attrmgr" "github.com/hyperledger/fabric-ca/lib/dbutil" "github.com/hyperledger/fabric-ca/lib/ldap" "github.com/hyperledger/fabric-ca/lib/spi" @@ -47,6 +46,7 @@ import ( "github.com/hyperledger/fabric-ca/lib/tls" "github.com/hyperledger/fabric-ca/util" "github.com/hyperledger/fabric/bccsp" + "github.com/hyperledger/fabric/common/attrmgr" "github.com/jmoiron/sqlx" _ "github.com/go-sql-driver/mysql" // import to support MySQL diff --git a/lib/client_test.go b/lib/client_test.go index 4daf5c874..07f06c385 100644 --- a/lib/client_test.go +++ b/lib/client_test.go @@ -29,10 +29,10 @@ import ( "github.com/cloudflare/cfssl/csr" "github.com/hyperledger/fabric-ca/api" - "github.com/hyperledger/fabric-ca/attrmgr" . "github.com/hyperledger/fabric-ca/lib" "github.com/hyperledger/fabric-ca/lib/tls" "github.com/hyperledger/fabric-ca/util" + "github.com/hyperledger/fabric/common/attrmgr" "github.com/stretchr/testify/assert" ) diff --git a/lib/serverrequestcontext.go b/lib/serverrequestcontext.go index 7316599f9..c3b1f4c12 100644 --- a/lib/serverrequestcontext.go +++ b/lib/serverrequestcontext.go @@ -30,10 +30,10 @@ import ( "github.com/cloudflare/cfssl/revoke" "github.com/cloudflare/cfssl/signer" "github.com/hyperledger/fabric-ca/api" - "github.com/hyperledger/fabric-ca/attrmgr" "github.com/hyperledger/fabric-ca/lib/spi" "github.com/hyperledger/fabric-ca/lib/tcert" "github.com/hyperledger/fabric-ca/util" + "github.com/hyperledger/fabric/common/attrmgr" "github.com/pkg/errors" ) diff --git a/lib/signer.go b/lib/signer.go index 654a95b94..203e09fb1 100644 --- a/lib/signer.go +++ b/lib/signer.go @@ -22,9 +22,9 @@ import ( "github.com/cloudflare/cfssl/log" "github.com/hyperledger/fabric-ca/api" - "github.com/hyperledger/fabric-ca/attrmgr" "github.com/hyperledger/fabric-ca/util" "github.com/hyperledger/fabric/bccsp" + "github.com/hyperledger/fabric/common/attrmgr" ) func newSigner(key bccsp.Key, cert []byte, id *Identity) *Signer {