-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcrypto_object.go
149 lines (135 loc) · 3.95 KB
/
crypto_object.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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package main
/*
#include "pkcs11go.h"
*/
import "C"
import (
"bytes"
"fmt"
"unsafe"
)
// CryptoObjectType represents a type of cryptoObject.
type CryptoObjectType int
const (
SessionObject CryptoObjectType = iota
TokenObject
)
// A cryptoObject related to a token.
type CryptoObject struct {
Handle C.CK_OBJECT_HANDLE // Object's handle
Type CryptoObjectType // Object type
Attributes Attributes // List of attributes of the object.
}
// A map of cryptoobjects
type CryptoObjects []*CryptoObject
// Transforms a C version of a cryptoobject in a CryptoObject Golang struct.
func CToCryptoObject(pAttributes C.CK_ATTRIBUTE_PTR, ulCount C.CK_ULONG) (*CryptoObject, error) {
attrSlice, err := CToAttributes(pAttributes, ulCount)
if err != nil {
return nil, err
}
var coType CryptoObjectType
tokenAttr, ok := attrSlice[C.CKA_TOKEN]
if !ok {
return nil, NewError("CToCryptoObject", "Token attribute not found", C.CKR_ATTRIBUTE_VALUE_INVALID)
}
isToken := C.CK_BBOOL(tokenAttr.Value[0])
if isToken == C.CK_FALSE {
coType = SessionObject
} else {
coType = TokenObject
}
object := &CryptoObject{
Type: coType,
Attributes: attrSlice,
}
return object, nil
}
// Equals returns true if the maps of crypto objects are equal.
func (objects CryptoObjects) Equals(objects2 CryptoObjects) bool {
if len(objects) != len(objects2) {
return false
}
for _, object := range objects {
ok := false
var object2 *CryptoObject
for _, object2 = range objects2 {
if object2.Handle == object.Handle {
ok = true
break
}
}
if !ok {
return false
}
if !object.Equals(object2) {
return false
}
}
return true
}
// Equals returns true if the crypto_objects are equal.
func (object *CryptoObject) Equals(object2 *CryptoObject) bool {
return object.Handle == object2.Handle &&
object.Attributes.Equals(object2.Attributes)
}
// https://stackoverflow.com/questions/28925179/cgo-how-to-pass-struct-array-from-c-to-go#28933938
func (object *CryptoObject) Match(attrs Attributes) bool {
for _, theirAttr := range attrs {
ourAttr, ok := object.Attributes[uint32(theirAttr.Type)]
if !ok {
return false
} else if bytes.Compare(ourAttr.Value, theirAttr.Value) != 0 {
return false
}
}
return true
}
// Returns an attribute with the type specified by the argument, or nil if the object does not have it.
func (object *CryptoObject) FindAttribute(attrType C.CK_ATTRIBUTE_TYPE) *Attribute {
if attr, ok := object.Attributes[uint32(attrType)]; ok {
return attr
}
return nil
}
// Copies the attributes of an object to a C pointer.
func (object *CryptoObject) CopyAttributes(pTemplate C.CK_ATTRIBUTE_PTR, ulCount C.CK_ULONG) error {
if pTemplate == nil {
return NewError("CryptoObject.CopyAttributes", "got NULL pointer", C.CKR_ARGUMENTS_BAD)
}
templateSlice := (*[1 << 30]C.CK_ATTRIBUTE)(unsafe.Pointer(pTemplate))[:ulCount:ulCount]
for i := 0; i < len(templateSlice); i++ {
src := object.FindAttribute(templateSlice[i]._type)
if src != nil {
err := src.ToC(&templateSlice[i])
if err != nil {
return err
}
} else {
return NewError("CryptoObject.CopyAttributes", fmt.Sprintf(
"Attribute number %d does not exist: %d", i, templateSlice[i]._type,
), C.CKR_ARGUMENTS_BAD)
}
}
return nil
}
// Copies the attributes of an object to a C pointer.
func (object *CryptoObject) EditAttributes(pTemplate C.CK_ATTRIBUTE_PTR, ulCount C.CK_ULONG, session *Session) error {
if pTemplate == nil {
return NewError("CryptoObject.CopyAttributes", "got NULL pointer", C.CKR_ARGUMENTS_BAD)
}
templateSlice := (*[1 << 30]C.CK_ATTRIBUTE)(unsafe.Pointer(pTemplate))[:ulCount:ulCount]
for i := 0; i < len(templateSlice); i++ {
newAttr := CToAttribute(templateSlice[i])
src := object.FindAttribute(templateSlice[i]._type)
if src != nil {
src.Value = newAttr.Value
} else {
object.Attributes[uint32(templateSlice[i]._type)] = newAttr
}
}
if err := session.SaveObject(object); err != nil {
return err
}
return nil
}