75 lines
1.9 KiB
Go
75 lines
1.9 KiB
Go
|
package protocol
|
||
|
|
||
|
import (
|
||
|
"encoding/asn1"
|
||
|
)
|
||
|
|
||
|
// Attribute ::= SEQUENCE {
|
||
|
// attrType OBJECT IDENTIFIER,
|
||
|
// attrValues SET OF AttributeValue }
|
||
|
//
|
||
|
// AttributeValue ::= ANY
|
||
|
type Attribute struct {
|
||
|
Type asn1.ObjectIdentifier
|
||
|
|
||
|
// This should be a SET OF ANY, but Go's asn1 parser can't handle slices of
|
||
|
// RawValues. Use value() to get an AnySet of the value.
|
||
|
RawValue []asn1.RawValue `asn1:"set"`
|
||
|
}
|
||
|
|
||
|
// NewAttribute creates a single-value Attribute.
|
||
|
func NewAttribute(attrType asn1.ObjectIdentifier, val interface{}) (attr Attribute, err error) {
|
||
|
var rv asn1.RawValue
|
||
|
if rv, err = RawValue(val); err != nil {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
attr = Attribute{attrType, []asn1.RawValue{rv}}
|
||
|
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// Attributes is a common Go type for SignedAttributes and UnsignedAttributes.
|
||
|
//
|
||
|
// SignedAttributes ::= SET SIZE (1..MAX) OF Attribute
|
||
|
//
|
||
|
// UnsignedAttributes ::= SET SIZE (1..MAX) OF Attribute
|
||
|
type Attributes []Attribute
|
||
|
|
||
|
// GetOnlyAttributeValueBytes gets an attribute value, returning an error if the
|
||
|
// attribute occurs multiple times or has multiple values.
|
||
|
func (attrs Attributes) GetOnlyAttributeValueBytes(oid asn1.ObjectIdentifier) (rv asn1.RawValue, err error) {
|
||
|
var vals [][]asn1.RawValue
|
||
|
if vals, err = attrs.GetValues(oid); err != nil {
|
||
|
return
|
||
|
}
|
||
|
if len(vals) != 1 {
|
||
|
err = ASN1Error{"bad attribute count"}
|
||
|
return
|
||
|
}
|
||
|
if len(vals[0]) != 1 {
|
||
|
err = ASN1Error{"bad attribute element count"}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
return vals[0][0], nil
|
||
|
}
|
||
|
|
||
|
// GetValues retreives the attributes with the given OID. A nil value is
|
||
|
// returned if the OPTIONAL SET of Attributes is missing from the SignerInfo. An
|
||
|
// empty slice is returned if the specified attribute isn't in the set.
|
||
|
func (attrs Attributes) GetValues(oid asn1.ObjectIdentifier) ([][]asn1.RawValue, error) {
|
||
|
if attrs == nil {
|
||
|
return nil, nil
|
||
|
}
|
||
|
|
||
|
vals := [][]asn1.RawValue{}
|
||
|
for _, attr := range attrs {
|
||
|
if attr.Type.Equal(oid) {
|
||
|
vals = append(vals, attr.RawValue)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return vals, nil
|
||
|
}
|