forked from InfiniteLoopSpace/go_S-MIME
-
Notifications
You must be signed in to change notification settings - Fork 0
/
attribute.go
74 lines (62 loc) · 1.91 KB
/
attribute.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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
}