File: object.go

package info (click to toggle)
golang-github-miekg-pkcs11 1.0.3%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, sid
  • size: 400 kB
  • sloc: makefile: 20; ansic: 19
file content (96 lines) | stat: -rw-r--r-- 2,809 bytes parent folder | download | duplicates (3)
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package p11

import (
	"errors"

	"github.com/miekg/pkcs11"
)

// Object represents a handle to a PKCS#11 object. It is attached to the
// session used to find it. Once that session is closed, operations on the
// Object will fail. Operations may also depend on the logged-in state of
// the application.
type Object struct {
	session      *sessionImpl
	objectHandle pkcs11.ObjectHandle
}

// Label returns the label of an object.
func (o Object) Label() (string, error) {
	labelBytes, err := o.Attribute(pkcs11.CKA_LABEL)
	if err != nil {
		return "", err
	}
	return string(labelBytes), nil
}

// Value returns an object's CKA_VALUE attribute, as bytes.
func (o Object) Value() ([]byte, error) {
	return o.Attribute(pkcs11.CKA_VALUE)
}

// Attribute gets exactly one attribute from a PKCS#11 object, returning
// an error if the attribute is not found, or if multiple attributes are
// returned. On success, it will return the value of that attribute as a slice
// of bytes. For attributes not present (i.e. CKR_ATTRIBUTE_TYPE_INVALID),
// Attribute returns a nil slice and nil error.
func (o Object) Attribute(attributeType uint) ([]byte, error) {
	o.session.Lock()
	defer o.session.Unlock()

	attrs, err := o.session.ctx.GetAttributeValue(o.session.handle, o.objectHandle,
		[]*pkcs11.Attribute{pkcs11.NewAttribute(attributeType, nil)})
	// The PKCS#11 spec states that C_GetAttributeValue may return
	// CKR_ATTRIBUTE_TYPE_INVALID if an object simply does not posses a given
	// attribute. We don't consider that an error, we just consider that
	// equivalent to an empty value.
	if err == pkcs11.Error(pkcs11.CKR_ATTRIBUTE_TYPE_INVALID) {
		return nil, nil
	} else if err != nil {
		return nil, err
	}
	if len(attrs) == 0 {
		return nil, errors.New("attribute not found")
	}
	if len(attrs) > 1 {
		return nil, errors.New("too many attributes found")
	}
	return attrs[0].Value, nil
}

// Set sets exactly one attribute on this object.
func (o Object) Set(attributeType uint, value []byte) error {
	o.session.Lock()
	defer o.session.Unlock()

	err := o.session.ctx.SetAttributeValue(o.session.handle, o.objectHandle,
		[]*pkcs11.Attribute{pkcs11.NewAttribute(attributeType, value)})
	if err != nil {
		return err
	}
	return nil
}

// Copy makes a copy of this object, with the attributes in template applied on
// top of it, if possible.
func (o Object) Copy(template []*pkcs11.Attribute) (Object, error) {
	s := o.session
	s.Lock()
	defer s.Unlock()
	newHandle, err := s.ctx.CopyObject(s.handle, o.objectHandle, template)
	if err != nil {
		return Object{}, err
	}
	return Object{
		session:      s,
		objectHandle: newHandle,
	}, nil
}

// Destroy destroys this object.
func (o Object) Destroy() error {
	s := o.session
	s.Lock()
	defer s.Unlock()
	return s.ctx.DestroyObject(s.handle, o.objectHandle)
}