generated from IBM/repo-template
/
pmap.go
235 lines (198 loc) · 8.72 KB
/
pmap.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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
//
// Copyright 2021 IBM Inc. All rights reserved
// SPDX-License-Identifier: Apache2.0
//
// CHANGE HISTORY
//
// Date Initials Description
// 12/08/2020 CLH T390301 - Add minimal touch functions
package common
import (
"encoding/binary"
"encoding/hex"
)
/*----------------------------------------------------------------------------*/
/* Type for working with ASN.1 sequences of the form defined in section 5.3 */
/* ("Serialized module state") of the EP11 wire formats document. */
/* */
/* Export WK and Export pending WK use ASN.1 sequences of this form for their */
/* input and output parameters. */
/*----------------------------------------------------------------------------*/
type ParameterMap struct {
pMap map[string][]byte
}
/*----------------------------------------------------------------------------*/
/* Tag values used in parameter maps */
/*----------------------------------------------------------------------------*/
/** Domain administrator subject key identifiers (SKIs) */
var PMTAG_DOMAIN_ADMIN_SKIS string = "0x000A"
/** Domain administrator certificates */
var PMTAG_DOMAIN_ADMIN_CERTS string = "0x000B"
/** Domain level information */
var PMTAG_DOMAIN_QUERY_INFO string = "0x000C"
/** Domain attributes */
var PMTAG_DOMAIN_ATTRIBUTES string = "0x000F"
/** Domain transaction counter */
var PMTAG_DOMAIN_TRANSACTION_COUNTER string = "0x0011"
/** OA certificate */
var PMTAG_OA_CERTIFICATE string = "0x0015"
/** Domain control points */
var PMTAG_DOMAIN_CONTROL_POINTS string = "0x0017"
/** ASN.1 structure containing an encrypted key part */
var PMTAG_ENCR_KEY_PART string = "0x0019"
/** ASN.1 structure containing an OA signature over encrypted key part */
var PMTAG_SIGNATURE_ENCR_KEY_PART string = "0x001A"
/** M policy (number of key parts required to reconstruct the key) */
var PMTAG_M_POLICY string = "0x001C"
/** KPH certificate containing a public key */
var PMTAG_KPH_CERTIFICATE string = "0x001D"
/** Scope restrictions on a state export request */
var PMTAG_STATE_SCOPE = "0x001F"
// See section 5.3 of the EP11 wire formats document for other defined tag
// values.
/*----------------------------------------------------------------------------*/
/* Creates a new parameter map and initializes it to empty. */
/*----------------------------------------------------------------------------*/
func NewParameterMap() ParameterMap {
var pm ParameterMap
pm.pMap = make(map[string][]byte, 0)
return pm
}
/*----------------------------------------------------------------------------*/
/* Initializes a parameter map using an input ASN.1 sequence of the form */
/* described in section 5.3 of the EP11 wire formats document. */
/* */
/* Input: */
/* []byte -- input ASN.1 sequence */
/* */
/* Outputs: */
/* ParameterMap -- the updated parameter map */
/* error -- reports invalid ASN.1 input sequence */
/*----------------------------------------------------------------------------*/
func (pm ParameterMap) Load(data []byte) (ParameterMap, error) {
// Make sure the map is initialized and discard any prior contents
pm.pMap = make(map[string][]byte, 0)
seqbytes, err := Asn1GetSequenceBytes(data, 0)
if err != nil {
return pm, err
}
next := 0
for next < len(seqbytes) {
octbytes, err := Asn1GetOctetStringBytes(seqbytes, next)
if err != nil {
return pm, err
}
next, err = Asn1SkipOctetString(seqbytes, next)
if err != nil {
return pm, err
}
tag := "0x" + hex.EncodeToString(octbytes[0:2])
auxInt := hex.EncodeToString(octbytes[2:6])
value := octbytes[2:]
// For entries that can repeat, add the index to the tag.
switch tag {
// Entries that can repeat
case PMTAG_DOMAIN_ADMIN_SKIS,
PMTAG_DOMAIN_ADMIN_CERTS,
PMTAG_DOMAIN_QUERY_INFO,
PMTAG_DOMAIN_ATTRIBUTES,
PMTAG_DOMAIN_TRANSACTION_COUNTER,
PMTAG_OA_CERTIFICATE,
PMTAG_DOMAIN_CONTROL_POINTS,
PMTAG_ENCR_KEY_PART,
PMTAG_SIGNATURE_ENCR_KEY_PART,
PMTAG_KPH_CERTIFICATE:
pm.pMap[tag+"+"+auxInt] = value
// Entries that cannot repeat
default:
pm.pMap[tag] = value
}
}
return pm, nil
}
/*----------------------------------------------------------------------------*/
/* Returns the auxiuliary integer associated with a parameter entry. */
/* */
/* Input: */
/* string -- tag identifying the parameter to retrieve */
/* */
/* Output: */
/* uint32 -- integer value associated with the parameter */
/*----------------------------------------------------------------------------*/
func (pm ParameterMap) GetAuxInt(tag string) uint32 {
data := pm.pMap[tag]
if data == nil {
panic("Map entry not found")
}
return binary.BigEndian.Uint32(data[0:4])
}
/*----------------------------------------------------------------------------*/
/* Returns data from a parameter map when an index value is used. */
/* */
/* Inputs: */
/* string -- tag identifying the parameter to retrieve */
/* uint32 -- index value to combine with the tag */
/* */
/* Output: */
/* []byte -- the parameter from the map, nil if no map entry exists */
/*----------------------------------------------------------------------------*/
func (pm ParameterMap) GetDataUsingIndex(tag string, index uint32) []byte {
auxInt := Uint32To4ByteSlice(index)
data := pm.pMap[tag+"+"+hex.EncodeToString(auxInt)]
if data == nil {
panic("Map entry not found")
}
return data[4:]
}
/*----------------------------------------------------------------------------*/
/* Adds a value to a parameter map. */
/* */
/* Inputs: */
/* string -- tag identifying the parameter to add */
/* uint32 -- index or associated integer */
/* []byte -- additional data */
/*----------------------------------------------------------------------------*/
func (pm ParameterMap) Put(tag string, index uint32, data []byte) {
auxInt := Uint32To4ByteSlice(index)
value := make([]byte, 0)
value = append(value, auxInt...)
value = append(value, data...)
// For entries that can repeat, add the index to the tag.
switch tag {
// Entries that can repeat
case PMTAG_DOMAIN_ADMIN_SKIS,
PMTAG_DOMAIN_ADMIN_CERTS,
PMTAG_DOMAIN_QUERY_INFO,
PMTAG_DOMAIN_ATTRIBUTES,
PMTAG_DOMAIN_TRANSACTION_COUNTER,
PMTAG_OA_CERTIFICATE,
PMTAG_DOMAIN_CONTROL_POINTS,
PMTAG_ENCR_KEY_PART,
PMTAG_SIGNATURE_ENCR_KEY_PART,
PMTAG_KPH_CERTIFICATE:
pm.pMap[tag+"+"+hex.EncodeToString(auxInt)] = value
// Entries that cannot repeat
default:
pm.pMap[tag] = value
}
}
/*----------------------------------------------------------------------------*/
/* Returns an ASN.1 sequence of octet strings for the parameters in the map. */
/* */
/* Output: */
/* []byte -- ASN.1 sequence */
/*----------------------------------------------------------------------------*/
func (pm ParameterMap) GenerateBytes() []byte {
elements := make([][]byte, 0)
for key, value := range pm.pMap {
tag, err := hex.DecodeString(key[2:6])
if err != nil {
panic("Invalid tag string in parameter map")
}
data := make([]byte, 0)
data = append(data, tag...)
data = append(data, value...)
elements = append(elements, Asn1FormOctetString(data))
}
return Asn1FormSequence(elements)
}