1 /*
2 * COPYRIGHT (c) International Business Machines Corp. 2001-2017
3 *
4 * This program is provided under the terms of the Common Public License,
5 * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
6 * software constitutes recipient's acceptance of CPL-1.0 terms which can be
7 * found in the file LICENSE file or at
8 * https://opensource.org/licenses/cpl1.0.php
9 */
10
11 // ASN.1 encoding/decoding routines
12 //
13 // This code is a mess...
14 //
15
16 #include <pthread.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <lber.h>
20
21 #include "pkcs11types.h"
22 #include "p11util.h"
23 #include "defs.h"
24 #include "host_defs.h"
25 #include "h_extern.h"
26 #include "trace.h"
27
28
29 //
30 //
ber_encode_INTEGER(CK_BBOOL length_only,CK_BYTE ** ber_int,CK_ULONG * ber_int_len,CK_BYTE * data,CK_ULONG data_len)31 CK_ULONG ber_encode_INTEGER(CK_BBOOL length_only,
32 CK_BYTE **ber_int,
33 CK_ULONG *ber_int_len, CK_BYTE *data,
34 CK_ULONG data_len)
35 {
36 CK_BYTE *buf = NULL;
37 CK_ULONG len, padding = 0;
38
39 // ber encoded integers are alway signed. So if the msb of the first byte
40 // is set, this would indicate an negative value if we just copy the
41 // (unsigned) big integer from *data to the ber buffer. So in this case
42 // a preceding 0x00 byte is stored before the actual data. The decode
43 // function does the reverse and may skip this padding.
44
45 if ((length_only && data_len && (!data || *data & 0x80))
46 || (data_len && data && *data & 0x80))
47 padding = 1;
48
49 // if data_len < 127 use short-form length id
50 // if data_len < 256 use long-form length id with 1-byte length field
51 // if data_len < 65536 use long-form length id with 2-byte length field
52 // if data_len < 16777216 use long-form length id with 3-byte length field
53 //
54 if (data_len + padding < 128) {
55 len = 1 + 1 + padding + data_len;
56 } else if (data_len + padding < 256) {
57 len = 1 + (1 + 1) + padding + data_len;
58 } else if (data_len + padding < (1 << 16)) {
59 len = 1 + (1 + 2) + padding + data_len;
60 } else if (data_len + padding < (1 << 24)) {
61 len = 1 + (1 + 3) + padding + data_len;
62 } else {
63 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
64 return CKR_FUNCTION_FAILED;
65 }
66 if (length_only == TRUE) {
67 *ber_int_len = len;
68 return CKR_OK;
69 }
70
71 buf = (CK_BYTE *) malloc(len);
72 if (!buf) {
73 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
74 return CKR_HOST_MEMORY;
75 }
76
77 if (data_len + padding < 128) {
78 buf[0] = 0x02;
79 buf[1] = data_len + padding;
80 if (padding) {
81 buf[2] = 0x00;
82 if (data && data_len)
83 memcpy(&buf[3], data, data_len);
84 } else {
85 if (data && data_len)
86 memcpy(&buf[2], data, data_len);
87 }
88 *ber_int_len = len;
89 *ber_int = buf;
90 return CKR_OK;
91 }
92
93 if (data_len + padding < 256) {
94 buf[0] = 0x02;
95 buf[1] = 0x81;
96 buf[2] = data_len + padding;
97 if (padding) {
98 buf[3] = 0x00;
99 if (data && data_len)
100 memcpy(&buf[4], data, data_len);
101 } else {
102 if (data && data_len)
103 memcpy(&buf[3], data, data_len);
104 }
105 *ber_int_len = len;
106 *ber_int = buf;
107 return CKR_OK;
108 }
109
110 if (data_len + padding < (1 << 16)) {
111 buf[0] = 0x02;
112 buf[1] = 0x82;
113 buf[2] = ((data_len + padding) >> 8) & 0xFF;
114 buf[3] = ((data_len + padding)) & 0xFF;
115 if (padding) {
116 buf[4] = 0x00;
117 if (data && data_len)
118 memcpy(&buf[5], data, data_len);
119 } else {
120 if (data && data_len)
121 memcpy(&buf[4], data, data_len);
122 }
123 *ber_int_len = len;
124 *ber_int = buf;
125 return CKR_OK;
126 }
127
128 if (data_len + padding < (1 << 24)) {
129 buf[0] = 0x02;
130 buf[1] = 0x83;
131 buf[2] = ((data_len + padding) >> 16) & 0xFF;
132 buf[3] = ((data_len + padding) >> 8) & 0xFF;
133 buf[4] = ((data_len + padding)) & 0xFF;
134 if (padding) {
135 buf[5] = 0x00;
136 if (data)
137 memcpy(&buf[6], data, data_len);
138 } else {
139 if (data)
140 memcpy(&buf[5], data, data_len);
141 }
142 *ber_int_len = len;
143 *ber_int = buf;
144 return CKR_OK;
145 }
146 // we should never reach this
147 //
148 free(buf);
149 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
150
151 return CKR_FUNCTION_FAILED;
152 }
153
154
155 //
156 //
ber_decode_INTEGER(CK_BYTE * ber_int,CK_BYTE ** data,CK_ULONG * data_len,CK_ULONG * field_len)157 CK_RV ber_decode_INTEGER(CK_BYTE *ber_int,
158 CK_BYTE **data, CK_ULONG *data_len,
159 CK_ULONG *field_len)
160 {
161 CK_ULONG len, length_octets;
162
163 if (!ber_int) {
164 TRACE_ERROR("Invalid function argument.\n");
165 return CKR_FUNCTION_FAILED;
166 }
167 if (ber_int[0] != 0x02) {
168 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
169 return CKR_FUNCTION_FAILED;
170 }
171 // ber encoded integers are alway signed. So it may be that the very first
172 // byte is just a padding 0x00 value because the following byte has the msb
173 // set and without the padding the value would indicate a negative value.
174 // However, opencryptoki always stores big integers 'unsigned' meaning
175 // even when the msb is set, there is no preceding 0x00. Even more some
176 // tests may fail e.g. the size in bytes of a modulo big integer should be
177 // modulo bits / 8 which is not true with preceeding 0x00 byte.
178
179 // short form lengths are easy
180 //
181 if ((ber_int[1] & 0x80) == 0) {
182 len = ber_int[1] & 0x7F;
183 *data = &ber_int[2];
184 *data_len = len;
185 if (ber_int[2] == 0x00) {
186 *data = &ber_int[3];
187 *data_len = len - 1;
188 }
189 *field_len = 1 + 1 + len;
190 return CKR_OK;
191 }
192
193 length_octets = ber_int[1] & 0x7F;
194
195 if (length_octets == 1) {
196 len = ber_int[2];
197 *data = &ber_int[3];
198 *data_len = len;
199 if (ber_int[3] == 0x00) {
200 *data = &ber_int[4];
201 *data_len = len - 1;
202 }
203 *field_len = 1 + (1 + 1) + len;
204 return CKR_OK;
205 }
206
207 if (length_octets == 2) {
208 len = ber_int[2];
209 len = len << 8;
210 len |= ber_int[3];
211 *data = &ber_int[4];
212 *data_len = len;
213 if (ber_int[4] == 0x00) {
214 *data = &ber_int[5];
215 *data_len = len - 1;
216 }
217 *field_len = 1 + (1 + 2) + len;
218 return CKR_OK;
219 }
220
221 if (length_octets == 3) {
222 len = ber_int[2];
223 len = len << 8;
224 len |= ber_int[3];
225 len = len << 8;
226 len |= ber_int[4];
227 *data = &ber_int[5];
228 *data_len = len;
229 if (ber_int[5] == 0x00) {
230 *data = &ber_int[6];
231 *data_len = len - 1;
232 }
233 *field_len = 1 + (1 + 3) + len;
234 return CKR_OK;
235 }
236 // > 3 length octets implies a length > 16MB which isn't possible for
237 // the coprocessor
238 //
239 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
240
241 return CKR_FUNCTION_FAILED;
242 }
243
244
245 //
246 //
ber_encode_OCTET_STRING(CK_BBOOL length_only,CK_BYTE ** str,CK_ULONG * str_len,CK_BYTE * data,CK_ULONG data_len)247 CK_RV ber_encode_OCTET_STRING(CK_BBOOL length_only,
248 CK_BYTE **str,
249 CK_ULONG *str_len, CK_BYTE *data,
250 CK_ULONG data_len)
251 {
252 CK_BYTE *buf = NULL;
253 CK_ULONG len;
254
255 // I only support Primitive encoding for OCTET STRINGS
256 //
257
258 // if data_len < 128 use short-form length id
259 // if data_len < 256 use long-form length id with 1-byte length field
260 // if data_len < 65536 use long-form length id with 2-byte length field
261 //
262
263 if (data_len < 128) {
264 len = 1 + 1 + data_len;
265 } else if (data_len < 256) {
266 len = 1 + (1 + 1) + data_len;
267 } else if (data_len < (1 << 16)) {
268 len = 1 + (1 + 2) + data_len;
269 } else if (data_len < (1 << 24)) {
270 len = 1 + (1 + 3) + data_len;
271 } else {
272 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
273 return CKR_FUNCTION_FAILED;
274 }
275 if (length_only == TRUE) {
276 *str_len = len;
277 return CKR_OK;
278 }
279
280 buf = (CK_BYTE *) malloc(len);
281 if (!buf) {
282 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
283 return CKR_HOST_MEMORY;
284 }
285
286 if (data_len < 128) {
287 buf[0] = 0x04; // primitive, OCTET STRING
288 buf[1] = data_len;
289 memcpy(&buf[2], data, data_len);
290
291 *str_len = len;
292 *str = buf;
293 return CKR_OK;
294 }
295
296 if (data_len < 256) {
297 buf[0] = 0x04; // primitive, OCTET STRING
298 buf[1] = 0x81; // length header -- 1 length octets
299 buf[2] = data_len;
300
301 memcpy(&buf[3], data, data_len);
302
303 *str_len = len;
304 *str = buf;
305 return CKR_OK;
306 }
307
308 if (data_len < (1 << 16)) {
309 buf[0] = 0x04; // primitive, OCTET STRING
310 buf[1] = 0x82; // length header -- 2 length octets
311 buf[2] = (data_len >> 8) & 0xFF;
312 buf[3] = (data_len) & 0xFF;
313
314 memcpy(&buf[4], data, data_len);
315
316 *str_len = len;
317 *str = buf;
318 return CKR_OK;
319 }
320
321 if (data_len < (1 << 24)) {
322 buf[0] = 0x04; // primitive, OCTET STRING
323 buf[1] = 0x83; // length header -- 3 length octets
324 buf[2] = (data_len >> 16) & 0xFF;
325 buf[3] = (data_len >> 8) & 0xFF;
326 buf[4] = (data_len) & 0xFF;
327
328 memcpy(&buf[5], data, data_len);
329
330 *str_len = len;
331 *str = buf;
332 return CKR_OK;
333 }
334 // we should never reach this
335 //
336 free(buf);
337 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
338
339 return CKR_FUNCTION_FAILED;
340 }
341
342
343 //
344 //
ber_decode_OCTET_STRING(CK_BYTE * str,CK_BYTE ** data,CK_ULONG * data_len,CK_ULONG * field_len)345 CK_RV ber_decode_OCTET_STRING(CK_BYTE *str,
346 CK_BYTE **data,
347 CK_ULONG *data_len, CK_ULONG *field_len)
348 {
349 CK_ULONG len, length_octets;
350
351 // I only support decoding primitive OCTET STRINGS
352 //
353
354 if (!str) {
355 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
356 return CKR_FUNCTION_FAILED;
357 }
358 if (str[0] != 0x04) {
359 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
360 return CKR_FUNCTION_FAILED;
361 }
362 // short form lengths are easy
363 //
364 if ((str[1] & 0x80) == 0) {
365 len = str[1] & 0x7F;
366
367 *data = &str[2];
368 *data_len = len;
369 *field_len = 1 + (1) + len;
370 return CKR_OK;
371 }
372
373 length_octets = str[1] & 0x7F;
374
375 if (length_octets == 1) {
376 len = str[2];
377
378 *data = &str[3];
379 *data_len = len;
380 *field_len = 1 + (1 + 1) + len;
381 return CKR_OK;
382 }
383
384 if (length_octets == 2) {
385 len = str[2];
386 len = len << 8;
387 len |= str[3];
388
389 *data = &str[4];
390 *data_len = len;
391 *field_len = 1 + (1 + 2) + len;
392 return CKR_OK;
393 }
394
395 if (length_octets == 3) {
396 len = str[2];
397 len = len << 8;
398 len |= str[3];
399 len = len << 8;
400 len |= str[4];
401
402 *data = &str[5];
403 *data_len = len;
404 *field_len = 1 + (1 + 3) + len;
405 return CKR_OK;
406 }
407 // > 3 length octets implies a length > 16MB
408 //
409 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
410
411 return CKR_FUNCTION_FAILED;
412 }
413
414 //
415 //
ber_decode_BIT_STRING(CK_BYTE * str,CK_BYTE ** data,CK_ULONG * data_len,CK_ULONG * field_len)416 CK_RV ber_decode_BIT_STRING(CK_BYTE *str,
417 CK_BYTE **data,
418 CK_ULONG *data_len, CK_ULONG *field_len)
419 {
420 CK_ULONG len, length_octets;
421
422 if (!str) {
423 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
424 return CKR_FUNCTION_FAILED;
425 }
426 if (str[0] != 0x03) {
427 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
428 return CKR_FUNCTION_FAILED;
429 }
430
431 if ((str[1] & 0x80) == 0) {
432 len = str[1] & 0x7F;
433
434 *data = &str[2];
435 *data_len = len;
436 *field_len = 1 + (1) + len;
437 return CKR_OK;
438 }
439
440 length_octets = str[1] & 0x7F;
441
442 if (length_octets == 1) {
443 len = str[2];
444
445 *data = &str[3];
446 *data_len = len;
447 *field_len = 1 + (1 + 1) + len;
448 return CKR_OK;
449 }
450
451 if (length_octets == 2) {
452 len = str[2];
453 len = len << 8;
454 len |= str[3];
455
456 *data = &str[4];
457 *data_len = len;
458 *field_len = 1 + (1 + 2) + len;
459 return CKR_OK;
460 }
461
462 if (length_octets == 3) {
463 len = str[2];
464 len = len << 8;
465 len |= str[3];
466 len = len << 8;
467 len |= str[4];
468
469 *data = &str[5];
470 *data_len = len;
471 *field_len = 1 + (1 + 3) + len;
472 return CKR_OK;
473 }
474 // > 3 length octets implies a length > 16MB
475 //
476 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
477
478 return CKR_FUNCTION_FAILED;
479 }
480
481 //
482 //
ber_encode_SEQUENCE(CK_BBOOL length_only,CK_BYTE ** seq,CK_ULONG * seq_len,CK_BYTE * data,CK_ULONG data_len)483 CK_RV ber_encode_SEQUENCE(CK_BBOOL length_only,
484 CK_BYTE **seq,
485 CK_ULONG *seq_len, CK_BYTE *data, CK_ULONG data_len)
486 {
487 CK_BYTE *buf = NULL;
488 CK_ULONG len;
489
490 // if data_len < 127 use short-form length id
491 // if data_len < 65536 use long-form length id with 2-byte length field
492 //
493
494 if (data_len < 128) {
495 len = 1 + 1 + data_len;
496 } else if (data_len < 256) {
497 len = 1 + (1 + 1) + data_len;
498 } else if (data_len < (1 << 16)) {
499 len = 1 + (1 + 2) + data_len;
500 } else if (data_len < (1 << 24)) {
501 len = 1 + (1 + 3) + data_len;
502 } else {
503 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
504 return CKR_FUNCTION_FAILED;
505 }
506 if (length_only == TRUE) {
507 *seq_len = len;
508 return CKR_OK;
509 }
510
511 buf = (CK_BYTE *) malloc(len);
512 if (!buf) {
513 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
514 return CKR_HOST_MEMORY;
515 }
516
517 if (data_len < 128) {
518 buf[0] = 0x30; // constructed, SEQUENCE
519 buf[1] = data_len;
520 memcpy(&buf[2], data, data_len);
521
522 *seq_len = len;
523 *seq = buf;
524 return CKR_OK;
525 }
526
527 if (data_len < 256) {
528 buf[0] = 0x30; // constructed, SEQUENCE
529 buf[1] = 0x81; // length header -- 1 length octets
530 buf[2] = data_len;
531
532 memcpy(&buf[3], data, data_len);
533
534 *seq_len = len;
535 *seq = buf;
536 return CKR_OK;
537 }
538
539 if (data_len < (1 << 16)) {
540 buf[0] = 0x30; // constructed, SEQUENCE
541 buf[1] = 0x82; // length header -- 2 length octets
542 buf[2] = (data_len >> 8) & 0xFF;
543 buf[3] = (data_len) & 0xFF;
544
545 memcpy(&buf[4], data, data_len);
546
547 *seq_len = len;
548 *seq = buf;
549 return CKR_OK;
550 }
551
552 if (data_len < (1 << 24)) {
553 buf[0] = 0x30; // constructed, SEQUENCE
554 buf[1] = 0x83; // length header -- 3 length octets
555 buf[2] = (data_len >> 16) & 0xFF;
556 buf[3] = (data_len >> 8) & 0xFF;
557 buf[4] = (data_len) & 0xFF;
558
559 memcpy(&buf[5], data, data_len);
560
561 *seq_len = len;
562 *seq = buf;
563 return CKR_OK;
564 }
565
566 free(buf);
567 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
568
569 return CKR_FUNCTION_FAILED;
570 }
571
572
573 //
574 //
ber_decode_SEQUENCE(CK_BYTE * seq,CK_BYTE ** data,CK_ULONG * data_len,CK_ULONG * field_len)575 CK_RV ber_decode_SEQUENCE(CK_BYTE *seq,
576 CK_BYTE **data, CK_ULONG *data_len,
577 CK_ULONG *field_len)
578 {
579 CK_ULONG len, length_octets;
580
581
582 if (!seq) {
583 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
584 return CKR_FUNCTION_FAILED;
585 }
586 if (seq[0] != 0x30) {
587 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
588 return CKR_FUNCTION_FAILED;
589 }
590 // short form lengths are easy
591 //
592 if ((seq[1] & 0x80) == 0) {
593 len = seq[1] & 0x7F;
594
595 *data = &seq[2];
596 *data_len = len;
597 *field_len = 1 + (1) + len;
598 return CKR_OK;
599 }
600
601 length_octets = seq[1] & 0x7F;
602
603 if (length_octets == 1) {
604 len = seq[2];
605
606 *data = &seq[3];
607 *data_len = len;
608 *field_len = 1 + (1 + 1) + len;
609 return CKR_OK;
610 }
611
612 if (length_octets == 2) {
613 len = seq[2];
614 len = len << 8;
615 len |= seq[3];
616
617 *data = &seq[4];
618 *data_len = len;
619 *field_len = 1 + (1 + 2) + len;
620 return CKR_OK;
621 }
622
623 if (length_octets == 3) {
624 len = seq[2];
625 len = len << 8;
626 len |= seq[3];
627 len = len << 8;
628 len |= seq[4];
629
630 *data = &seq[5];
631 *data_len = len;
632 *field_len = 1 + (1 + 3) + len;
633 return CKR_OK;
634 }
635 // > 3 length octets implies a length > 16MB
636 //
637 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
638
639 return CKR_FUNCTION_FAILED;
640 }
641
642 //
643 //
ber_encode_CHOICE(CK_BBOOL length_only,CK_BYTE option,CK_BYTE ** str,CK_ULONG * str_len,CK_BYTE * data,CK_ULONG data_len)644 CK_RV ber_encode_CHOICE(CK_BBOOL length_only,
645 CK_BYTE option,
646 CK_BYTE **str,
647 CK_ULONG *str_len, CK_BYTE *data, CK_ULONG data_len)
648 {
649 CK_BYTE *buf = NULL;
650 CK_ULONG len;
651
652 /*
653 * if data_len < 127 use short-form length id
654 * if data_len < 65536 use long-form length id with 2-byte length field
655 */
656
657 if (data_len < 128) {
658 len = 1 + 1 + data_len;
659 } else if (data_len < 256) {
660 len = 1 + (1 + 1) + data_len;
661 } else if (data_len < (1 << 16)) {
662 len = 1 + (1 + 2) + data_len;
663 } else if (data_len < (1 << 24)) {
664 len = 1 + (1 + 3) + data_len;
665 } else {
666 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
667 return CKR_FUNCTION_FAILED;
668 }
669 if (length_only == TRUE) {
670 *str_len = len;
671 return CKR_OK;
672 }
673
674 buf = (CK_BYTE *) malloc(len);
675 if (!buf) {
676 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
677 return CKR_HOST_MEMORY;
678 }
679
680 if (data_len < 128) {
681 buf[0] = 0xA0 | option; // constructed, CHOICE
682 buf[1] = data_len;
683 memcpy(&buf[2], data, data_len);
684
685 *str_len = len;
686 *str = buf;
687 return CKR_OK;
688 }
689
690 if (data_len < 256) {
691 buf[0] = 0xA0 | option; // constructed, CHOICE
692 buf[1] = 0x81; // length header -- 1 length octets
693 buf[2] = data_len;
694
695 memcpy(&buf[3], data, data_len);
696
697 *str_len = len;
698 *str = buf;
699 return CKR_OK;
700 }
701
702 if (data_len < (1 << 16)) {
703 buf[0] = 0xA0 | option; // constructed, CHOICE
704 buf[1] = 0x82; // length header -- 2 length octets
705 buf[2] = (data_len >> 8) & 0xFF;
706 buf[3] = (data_len) & 0xFF;
707
708 memcpy(&buf[4], data, data_len);
709
710 *str_len = len;
711 *str = buf;
712 return CKR_OK;
713 }
714 if (data_len < (1 << 24)) {
715 buf[0] = 0xA0 | option; // constructed, CHOICE
716 buf[1] = 0x83; // length header -- 3 length octets
717 buf[2] = (data_len >> 16) & 0xFF;
718 buf[3] = (data_len >> 8) & 0xFF;
719 buf[4] = (data_len) & 0xFF;
720
721 memcpy(&buf[5], data, data_len);
722
723 *str_len = len;
724 *str = buf;
725 return CKR_OK;
726 }
727
728 free(buf);
729 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
730
731 return CKR_FUNCTION_FAILED;
732 }
733
734 // PrivateKeyInfo ::= SEQUENCE {
735 // version Version -- always '0' for now
736 // privateKeyAlgorithm PrivateKeyAlgorithmIdentifier
737 // privateKey PrivateKey
738 // attributes
739 // }
740 //
ber_decode_CHOICE(CK_BYTE * choice,CK_BYTE ** data,CK_ULONG * data_len,CK_ULONG * field_len,CK_ULONG * option)741 CK_RV ber_decode_CHOICE(CK_BYTE *choice,
742 CK_BYTE **data,
743 CK_ULONG *data_len, CK_ULONG *field_len,
744 CK_ULONG *option)
745 {
746 CK_ULONG len, length_octets;
747
748
749 if (!choice) {
750 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
751 return CKR_FUNCTION_FAILED;
752 }
753
754 if ((choice[0] & 0xE0) != 0xA0) {
755 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
756 return CKR_FUNCTION_FAILED;
757 }
758
759 *option = choice[0] & 0x1F;
760
761 // short form lengths are easy
762 //
763 if ((choice[1] & 0x80) == 0) {
764 len = choice[1] & 0x7F;
765 *data = &choice[2];
766 *data_len = len;
767 *field_len = 1 + (1) + len;
768 return CKR_OK;
769 }
770
771 length_octets = choice[1] & 0x7F;
772
773 if (length_octets == 1) {
774 len = choice[2];
775 *data = &choice[3];
776 *data_len = len;
777 *field_len = 1 + (1 + 1) + len;
778 return CKR_OK;
779 }
780
781 if (length_octets == 2) {
782 len = choice[2];
783 len = len << 8;
784 len |= choice[3];
785 *data = &choice[4];
786 *data_len = len;
787 *field_len = 1 + (1 + 2) + len;
788 return CKR_OK;
789 }
790
791 if (length_octets == 3) {
792 len = choice[2];
793 len = len << 8;
794 len |= choice[3];
795 len = len << 8;
796 len |= choice[4];
797 *data = &choice[5];
798 *data_len = len;
799 *field_len = 1 + (1 + 3) + len;
800 return CKR_OK;
801 }
802 // > 3 length octets implies a length > 16MB
803 //
804 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
805 return CKR_FUNCTION_FAILED;
806 }
807
808 // PrivateKeyInfo ::= SEQUENCE {
809 // version Version -- always '0' for now
810 // privateKeyAlgorithm PrivateKeyAlgorithmIdentifier
811 // privateKey PrivateKey
812 // attributes
813 // }
814 //
ber_encode_PrivateKeyInfo(CK_BBOOL length_only,CK_BYTE ** data,CK_ULONG * data_len,CK_BYTE * algorithm_id,CK_ULONG algorithm_id_len,CK_BYTE * priv_key,CK_ULONG priv_key_len)815 CK_RV ber_encode_PrivateKeyInfo(CK_BBOOL length_only,
816 CK_BYTE **data,
817 CK_ULONG *data_len,
818 CK_BYTE *algorithm_id,
819 CK_ULONG algorithm_id_len,
820 CK_BYTE *priv_key, CK_ULONG priv_key_len)
821 {
822 CK_BYTE *buf = NULL;
823 CK_BYTE *tmp = NULL;
824 CK_BYTE version[] = { 0 };
825 CK_ULONG len, total;
826 CK_RV rc;
827
828 len = 0;
829
830 rc = ber_encode_INTEGER(TRUE, NULL, &total, version, sizeof(version));
831 if (rc != CKR_OK) {
832 TRACE_DEVEL("ber_encode_INTEGER failed\n");
833 return rc;
834 } else {
835 len += total;
836 }
837
838 len += algorithm_id_len;
839
840 rc = ber_encode_OCTET_STRING(TRUE, NULL, &total, priv_key, priv_key_len);
841 if (rc != CKR_OK) {
842 TRACE_DEVEL("ber_encode_OCTET_STRING failed\n");
843 return rc;
844 }
845
846 len += total;
847
848 // for this stuff, attributes can be suppressed.
849 //
850
851 if (length_only == TRUE) {
852 rc = ber_encode_SEQUENCE(TRUE, NULL, &total, NULL, len);
853
854 if (rc == CKR_OK)
855 *data_len = total;
856 if (rc != CKR_OK)
857 TRACE_DEVEL("ber_encode_SEQUENCE failed\n");
858 return rc;
859 }
860
861 buf = (CK_BYTE *) malloc(len);
862 if (!buf) {
863 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
864 return CKR_HOST_MEMORY;
865 }
866 len = 0;
867 rc = ber_encode_INTEGER(FALSE, &tmp, &total, version, sizeof(version));
868 if (rc != CKR_OK) {
869 TRACE_DEVEL("ber_encode_INTEGER failed\n");
870 goto error;
871 }
872 if (tmp != NULL) {
873 memcpy(buf + len, tmp, total);
874 len += total;
875 free(tmp);
876 }
877
878 memcpy(buf + len, algorithm_id, algorithm_id_len);
879 len += algorithm_id_len;
880
881 rc = ber_encode_OCTET_STRING(FALSE, &tmp, &total, priv_key, priv_key_len);
882 if (rc != CKR_OK) {
883 TRACE_DEVEL("ber_encode_OCTET_STRING failed\n");
884 goto error;
885 }
886 memcpy(buf + len, tmp, total);
887 len += total;
888 free(tmp);
889
890 rc = ber_encode_SEQUENCE(FALSE, data, data_len, buf, len);
891 if (rc != CKR_OK)
892 TRACE_DEVEL("ber_encode_SEQUENCE failed\n");
893
894 error:
895 free(buf);
896
897 return rc;
898 }
899
900
901 //
902 //
ber_decode_PrivateKeyInfo(CK_BYTE * data,CK_ULONG data_len,CK_BYTE ** algorithm,CK_ULONG * alg_len,CK_BYTE ** priv_key)903 CK_RV ber_decode_PrivateKeyInfo(CK_BYTE *data,
904 CK_ULONG data_len,
905 CK_BYTE **algorithm,
906 CK_ULONG *alg_len, CK_BYTE **priv_key)
907 {
908 CK_BYTE *buf = NULL;
909 CK_BYTE *alg = NULL;
910 CK_BYTE *ver = NULL;
911 CK_ULONG buf_len, offset, len, field_len;
912 CK_RV rc;
913
914 if (!data || (data_len == 0)) {
915 TRACE_ERROR("Invalid function arguments.\n");
916 return CKR_FUNCTION_FAILED;
917 }
918 rc = ber_decode_SEQUENCE(data, &buf, &buf_len, &field_len);
919 if (rc != CKR_OK) {
920 TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
921 return rc;
922 }
923 // version -- we just ignore this
924 //
925 offset = 0;
926 rc = ber_decode_INTEGER(buf + offset, &ver, &len, &field_len);
927 if (rc != CKR_OK) {
928 TRACE_DEVEL("ber_decode_INTEGER failed\n");
929 return rc;
930 }
931 offset += field_len;
932
933 // 'buf' is now pointing to the PrivateKeyAlgorithmIdentifier
934 //
935 rc = ber_decode_SEQUENCE(buf + offset, &alg, &len, &field_len);
936 if (rc != CKR_OK) {
937 TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
938 return rc;
939 }
940 *algorithm = alg;
941 *alg_len = len;
942
943 rc = ber_decode_OCTET_STRING(alg + len, priv_key, &buf_len, &field_len);
944 if (rc != CKR_OK)
945 TRACE_DEVEL("ber_decode_OCTET_STRING failed\n");
946
947 return rc;
948 }
949
950
951 // RSAPrivateKey ::= SEQUENCE {
952 // version Version -- always '0' for now
953 // modulus INTEGER
954 // publicExponent INTEGER
955 // if secure key
956 // opaque OCTET_STRING
957 // else
958 // privateExponent INTEGER
959 // prime1 INTEGER
960 // prime2 INTEGER
961 // exponent1 INTEGER
962 // exponent2 INTEGER
963 // coefficient INTEGER
964 // }
965 //
ber_encode_RSAPrivateKey(CK_BBOOL length_only,CK_BYTE ** data,CK_ULONG * data_len,CK_ATTRIBUTE * modulus,CK_ATTRIBUTE * publ_exp,CK_ATTRIBUTE * priv_exp,CK_ATTRIBUTE * prime1,CK_ATTRIBUTE * prime2,CK_ATTRIBUTE * exponent1,CK_ATTRIBUTE * exponent2,CK_ATTRIBUTE * coeff,CK_ATTRIBUTE * opaque)966 CK_RV ber_encode_RSAPrivateKey(CK_BBOOL length_only,
967 CK_BYTE **data,
968 CK_ULONG *data_len,
969 CK_ATTRIBUTE *modulus,
970 CK_ATTRIBUTE *publ_exp,
971 CK_ATTRIBUTE *priv_exp,
972 CK_ATTRIBUTE *prime1,
973 CK_ATTRIBUTE *prime2,
974 CK_ATTRIBUTE *exponent1,
975 CK_ATTRIBUTE *exponent2,
976 CK_ATTRIBUTE *coeff, CK_ATTRIBUTE *opaque)
977 {
978 CK_BYTE *buf = NULL;
979 CK_BYTE *buf2 = NULL;
980 CK_ULONG len, offset;
981 CK_BYTE version[] = { 0 };
982 CK_RV rc;
983
984
985 offset = 0;
986 rc = 0;
987
988 rc |= ber_encode_INTEGER(TRUE, NULL, &len, NULL, sizeof(version));
989 offset += len;
990 rc |= ber_encode_INTEGER(TRUE, NULL, &len, NULL, modulus->ulValueLen);
991 offset += len;
992 rc |= ber_encode_INTEGER(TRUE, NULL, &len, NULL, publ_exp->ulValueLen);
993 offset += len;
994 if (opaque != NULL) {
995 rc |= ber_encode_INTEGER(TRUE, NULL, &len, NULL, opaque->ulValueLen);
996 offset += len;
997 } else {
998 rc |= ber_encode_INTEGER(TRUE, NULL, &len, NULL, priv_exp->ulValueLen);
999 offset += len;
1000 rc |= ber_encode_INTEGER(TRUE, NULL, &len, NULL, prime1->ulValueLen);
1001 offset += len;
1002 rc |= ber_encode_INTEGER(TRUE, NULL, &len, NULL, prime2->ulValueLen);
1003 offset += len;
1004 rc |= ber_encode_INTEGER(TRUE, NULL, &len, NULL, exponent1->ulValueLen);
1005 offset += len;
1006 rc |= ber_encode_INTEGER(TRUE, NULL, &len, NULL, exponent2->ulValueLen);
1007 offset += len;
1008 rc |= ber_encode_INTEGER(TRUE, NULL, &len, NULL, coeff->ulValueLen);
1009 offset += len;
1010 }
1011
1012 if (rc != CKR_OK) {
1013 TRACE_DEVEL("ber_encode_INTEGER failed\n");
1014 return CKR_FUNCTION_FAILED;
1015 }
1016 if (length_only == TRUE) {
1017 rc = ber_encode_SEQUENCE(TRUE, NULL, &len, NULL, offset);
1018 if (rc != CKR_OK) {
1019 TRACE_DEVEL("ber_encode_SEQUENCE failed\n");
1020 return rc;
1021 }
1022 rc = ber_encode_PrivateKeyInfo(TRUE,
1023 NULL, data_len,
1024 NULL, ber_AlgIdRSAEncryptionLen,
1025 NULL, len);
1026 if (rc != CKR_OK) {
1027 TRACE_DEVEL("ber_encode_PrivateKeyInfo failed\n");
1028 return rc;
1029 }
1030 return rc;
1031 }
1032
1033 buf = (CK_BYTE *) malloc(offset);
1034 if (!buf) {
1035 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
1036 return CKR_HOST_MEMORY;
1037 }
1038 offset = 0;
1039 rc = 0;
1040
1041 rc = ber_encode_INTEGER(FALSE, &buf2, &len, version, sizeof(version));
1042 if (rc != CKR_OK) {
1043 TRACE_DEVEL("ber_encode_INTEGER failed\n");
1044 goto error;
1045 }
1046 if (buf2 != NULL) {
1047 memcpy(buf + offset, buf2, len);
1048 offset += len;
1049 free(buf2);
1050 buf2 = NULL;
1051 }
1052
1053 rc = ber_encode_INTEGER(FALSE, &buf2, &len,
1054 (CK_BYTE *) modulus + sizeof(CK_ATTRIBUTE),
1055 modulus->ulValueLen);
1056 if (rc != CKR_OK) {
1057 TRACE_DEVEL("ber_encode_INTEGER failed\n");
1058 goto error;
1059 }
1060 if (buf2 != NULL) {
1061 memcpy(buf + offset, buf2, len);
1062 offset += len;
1063 free(buf2);
1064 buf2 = NULL;
1065 }
1066
1067 rc = ber_encode_INTEGER(FALSE, &buf2, &len,
1068 (CK_BYTE *) publ_exp + sizeof(CK_ATTRIBUTE),
1069 publ_exp->ulValueLen);
1070 if (rc != CKR_OK) {
1071 TRACE_DEVEL("ber_encode_INTEGER failed\n");
1072 goto error;
1073 }
1074 if (buf2 != NULL) {
1075 memcpy(buf + offset, buf2, len);
1076 offset += len;
1077 free(buf2);
1078 buf2 = NULL;
1079 }
1080
1081 if (opaque != NULL) {
1082 // the CKA_IBM_OPAQUE attrib
1083 rc = ber_encode_OCTET_STRING(FALSE, &buf2, &len,
1084 (CK_BYTE *) opaque +
1085 sizeof(CK_ATTRIBUTE), opaque->ulValueLen);
1086 if (rc != CKR_OK) {
1087 TRACE_DEVEL("ber_encode_OCTET_STRING failed\n");
1088 goto error;
1089 }
1090 memcpy(buf + offset, buf2, len);
1091 offset += len;
1092 free(buf2);
1093 buf2 = NULL;
1094 } else {
1095 rc = ber_encode_INTEGER(FALSE, &buf2, &len,
1096 (CK_BYTE *) priv_exp + sizeof(CK_ATTRIBUTE),
1097 priv_exp->ulValueLen);
1098 if (rc != CKR_OK) {
1099 TRACE_DEVEL("ber_encode_INTEGER failed\n");
1100 goto error;
1101 }
1102 if (buf2 != NULL) {
1103 memcpy(buf + offset, buf2, len);
1104 offset += len;
1105 free(buf2);
1106 buf2 = NULL;
1107 }
1108
1109 rc = ber_encode_INTEGER(FALSE, &buf2, &len,
1110 (CK_BYTE *) prime1 + sizeof(CK_ATTRIBUTE),
1111 prime1->ulValueLen);
1112 if (rc != CKR_OK) {
1113 TRACE_DEVEL("ber_encode_INTEGER failed\n");
1114 goto error;
1115 }
1116 if (buf2 != NULL) {
1117 memcpy(buf + offset, buf2, len);
1118 offset += len;
1119 free(buf2);
1120 buf2 = NULL;
1121 }
1122
1123 rc = ber_encode_INTEGER(FALSE, &buf2, &len,
1124 (CK_BYTE *) prime2 + sizeof(CK_ATTRIBUTE),
1125 prime2->ulValueLen);
1126 if (rc != CKR_OK) {
1127 TRACE_DEVEL("ber_encode_INTEGER failed\n");
1128 goto error;
1129 }
1130 if (buf2 != NULL) {
1131 memcpy(buf + offset, buf2, len);
1132 offset += len;
1133 free(buf2);
1134 buf2 = NULL;
1135 }
1136
1137 rc = ber_encode_INTEGER(FALSE, &buf2, &len,
1138 (CK_BYTE *) exponent1 + sizeof(CK_ATTRIBUTE),
1139 exponent1->ulValueLen);
1140 if (rc != CKR_OK) {
1141 TRACE_DEVEL("ber_encode_INTEGER failed\n");
1142 goto error;
1143 }
1144 if (buf2 != NULL) {
1145 memcpy(buf + offset, buf2, len);
1146 offset += len;
1147 free(buf2);
1148 buf2 = NULL;
1149 }
1150
1151 rc = ber_encode_INTEGER(FALSE, &buf2, &len,
1152 (CK_BYTE *) exponent2 + sizeof(CK_ATTRIBUTE),
1153 exponent2->ulValueLen);
1154 if (rc != CKR_OK) {
1155 TRACE_DEVEL("ber_encode_INTEGER failed\n");
1156 goto error;
1157 }
1158 if (buf2 != NULL) {
1159 memcpy(buf + offset, buf2, len);
1160 offset += len;
1161 free(buf2);
1162 buf2 = NULL;
1163 }
1164
1165 rc = ber_encode_INTEGER(FALSE, &buf2, &len,
1166 (CK_BYTE *) coeff + sizeof(CK_ATTRIBUTE),
1167 coeff->ulValueLen);
1168 if (rc != CKR_OK) {
1169 TRACE_DEVEL("ber_encode_INTEGER failed\n");
1170 goto error;
1171 }
1172 if (buf2 != NULL) {
1173 memcpy(buf + offset, buf2, len);
1174 offset += len;
1175 free(buf2);
1176 buf2 = NULL;
1177 }
1178 }
1179
1180 rc = ber_encode_SEQUENCE(FALSE, &buf2, &len, buf, offset);
1181 if (rc != CKR_OK) {
1182 TRACE_DEVEL("ber_encode_SEQUENCE failed\n");
1183 goto error;
1184 }
1185 rc = ber_encode_PrivateKeyInfo(FALSE,
1186 data, data_len,
1187 ber_AlgIdRSAEncryption,
1188 ber_AlgIdRSAEncryptionLen, buf2, len);
1189 if (rc != CKR_OK) {
1190 TRACE_ERROR("ber_encode_PrivateKeyInfo failed\n");
1191 }
1192 error:
1193 if (buf2)
1194 free(buf2);
1195 if (buf)
1196 free(buf);
1197
1198 return rc;
1199 }
1200
1201
1202 //
1203 //
ber_decode_RSAPrivateKey(CK_BYTE * data,CK_ULONG data_len,CK_ATTRIBUTE ** modulus,CK_ATTRIBUTE ** publ_exp,CK_ATTRIBUTE ** priv_exp,CK_ATTRIBUTE ** prime1,CK_ATTRIBUTE ** prime2,CK_ATTRIBUTE ** exponent1,CK_ATTRIBUTE ** exponent2,CK_ATTRIBUTE ** coeff,CK_ATTRIBUTE ** opaque,CK_BBOOL isopaque)1204 CK_RV ber_decode_RSAPrivateKey(CK_BYTE *data,
1205 CK_ULONG data_len,
1206 CK_ATTRIBUTE **modulus,
1207 CK_ATTRIBUTE **publ_exp,
1208 CK_ATTRIBUTE **priv_exp,
1209 CK_ATTRIBUTE **prime1,
1210 CK_ATTRIBUTE **prime2,
1211 CK_ATTRIBUTE **exponent1,
1212 CK_ATTRIBUTE **exponent2,
1213 CK_ATTRIBUTE **coeff,
1214 CK_ATTRIBUTE **opaque, CK_BBOOL isopaque)
1215 {
1216 CK_ATTRIBUTE *n_attr = NULL;
1217 CK_ATTRIBUTE *e_attr = NULL;
1218 CK_ATTRIBUTE *d_attr = NULL;
1219 CK_ATTRIBUTE *p_attr = NULL;
1220 CK_ATTRIBUTE *q_attr = NULL;
1221 CK_ATTRIBUTE *e1_attr = NULL;
1222 CK_ATTRIBUTE *e2_attr = NULL;
1223 CK_ATTRIBUTE *coeff_attr = NULL;
1224 CK_ATTRIBUTE *o_attr = NULL;
1225
1226 CK_BYTE *alg = NULL;
1227 CK_BYTE *rsa_priv_key = NULL;
1228 CK_BYTE *buf = NULL;
1229 CK_BYTE *tmp = NULL;
1230 CK_ULONG offset, buf_len, field_len, len;
1231 CK_RV rc;
1232
1233 rc = ber_decode_PrivateKeyInfo(data, data_len, &alg, &len, &rsa_priv_key);
1234 if (rc != CKR_OK) {
1235 TRACE_DEVEL("ber_decode_PrivateKeyInfo failed\n");
1236 return rc;
1237 }
1238 // make sure we're dealing with an RSA key
1239 //
1240 if (memcmp(alg, ber_rsaEncryption, ber_rsaEncryptionLen) != 0) {
1241 // probably ought to use a different error
1242 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
1243 return CKR_FUNCTION_FAILED;
1244 }
1245 rc = ber_decode_SEQUENCE(rsa_priv_key, &buf, &buf_len, &field_len);
1246 if (rc != CKR_OK)
1247 return rc;
1248
1249 // parse the RSAPrivateKey
1250 //
1251 offset = 0;
1252
1253 // Version
1254 //
1255 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
1256 if (rc != CKR_OK) {
1257 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1258 goto cleanup;
1259 }
1260 offset += field_len;
1261
1262 // modulus
1263 //
1264 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
1265 if (rc != CKR_OK) {
1266 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1267 goto cleanup;
1268 }
1269 offset += field_len;
1270
1271 // public exponent
1272 //
1273 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
1274 if (rc != CKR_OK) {
1275 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1276 goto cleanup;
1277 }
1278 offset += field_len;
1279
1280 if (isopaque) {
1281 // opaque attribute, the CCA key
1282 //
1283 rc = ber_decode_OCTET_STRING(buf + offset, &tmp, &len, &field_len);
1284 if (rc != CKR_OK) {
1285 TRACE_DEVEL("ber_decode_OCTET_STRING failed\n");
1286 goto cleanup;
1287 }
1288 offset += field_len;
1289 } else {
1290
1291 // private exponent
1292 //
1293 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
1294 if (rc != CKR_OK) {
1295 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1296 goto cleanup;
1297 }
1298 offset += field_len;
1299
1300 // prime #1
1301 //
1302 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
1303 if (rc != CKR_OK) {
1304 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1305 goto cleanup;
1306 }
1307 offset += field_len;
1308
1309 // prime #2
1310 //
1311 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
1312 if (rc != CKR_OK) {
1313 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1314 goto cleanup;
1315 }
1316 offset += field_len;
1317
1318 // exponent #1
1319 //
1320 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
1321 if (rc != CKR_OK) {
1322 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1323 goto cleanup;
1324 }
1325 offset += field_len;
1326
1327 // exponent #2
1328 //
1329 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
1330 if (rc != CKR_OK) {
1331 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1332 goto cleanup;
1333 }
1334 offset += field_len;
1335
1336 // coefficient
1337 //
1338 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
1339 if (rc != CKR_OK) {
1340 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1341 goto cleanup;
1342 }
1343 offset += field_len;
1344
1345 if (offset > buf_len) {
1346 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
1347 return CKR_FUNCTION_FAILED;
1348 }
1349 }
1350
1351 //
1352 // it looks okay. build the attributes
1353 //
1354
1355 offset = 0;
1356
1357 // skip the version
1358 //
1359 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
1360 if (rc != CKR_OK) {
1361 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1362 goto cleanup;
1363 }
1364 offset += field_len;
1365
1366 // modulus
1367 //
1368 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
1369 if (rc != CKR_OK) {
1370 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1371 goto cleanup;
1372 } else {
1373 rc = build_attribute(CKA_MODULUS, tmp, len, &n_attr);
1374 if (rc != CKR_OK) {
1375 TRACE_DEVEL("build_attribute failed\n");
1376 goto cleanup;
1377 }
1378 offset += field_len;
1379 }
1380
1381 // public exponent
1382 //
1383 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
1384 if (rc != CKR_OK) {
1385 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1386 goto cleanup;
1387 } else {
1388 rc = build_attribute(CKA_PUBLIC_EXPONENT, tmp, len, &e_attr);
1389 if (rc != CKR_OK) {
1390 TRACE_DEVEL("build_attribute failed\n");
1391 goto cleanup;
1392 }
1393 offset += field_len;
1394 }
1395
1396 if (isopaque) {
1397 // opaque attribute, the CCA key
1398 //
1399 rc = ber_decode_OCTET_STRING(buf + offset, &tmp, &len, &field_len);
1400 if (rc != CKR_OK) {
1401 TRACE_DEVEL("ber_decode_OCTET_STRING failed\n");
1402 goto cleanup;
1403 } else {
1404 rc = build_attribute(CKA_IBM_OPAQUE, tmp, len, &o_attr);
1405 if (rc != CKR_OK) {
1406 TRACE_DEVEL("build_attribute failed\n");
1407 goto cleanup;
1408 }
1409 offset += field_len;
1410 }
1411 *opaque = o_attr;
1412 } else {
1413 // private exponent
1414 //
1415 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
1416 if (rc != CKR_OK) {
1417 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1418 goto cleanup;
1419 } else {
1420 rc = build_attribute(CKA_PRIVATE_EXPONENT, tmp, len, &d_attr);
1421 if (rc != CKR_OK) {
1422 TRACE_DEVEL("build_attribute failed\n");
1423 goto cleanup;
1424 }
1425 offset += field_len;
1426 }
1427
1428 // prime #1
1429 //
1430 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
1431 if (rc != CKR_OK) {
1432 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1433 goto cleanup;
1434 } else {
1435 rc = build_attribute(CKA_PRIME_1, tmp, len, &p_attr);
1436 if (rc != CKR_OK) {
1437 TRACE_DEVEL("build_attribute failed\n");
1438 goto cleanup;
1439 }
1440 offset += field_len;
1441 }
1442
1443 // prime #2
1444 //
1445 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
1446 if (rc != CKR_OK) {
1447 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1448 goto cleanup;
1449 } else {
1450 rc = build_attribute(CKA_PRIME_2, tmp, len, &q_attr);
1451 if (rc != CKR_OK) {
1452 TRACE_DEVEL("build_attribute failed\n");
1453 goto cleanup;
1454 }
1455 offset += field_len;
1456 }
1457
1458 // exponent #1
1459 //
1460 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
1461 if (rc != CKR_OK) {
1462 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1463 goto cleanup;
1464 } else {
1465 rc = build_attribute(CKA_EXPONENT_1, tmp, len, &e1_attr);
1466 if (rc != CKR_OK) {
1467 TRACE_DEVEL("build_attribute failed\n");
1468 goto cleanup;
1469 }
1470 offset += field_len;
1471 }
1472
1473 // exponent #2
1474 //
1475 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
1476 if (rc != CKR_OK) {
1477 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1478 goto cleanup;
1479 } else {
1480 rc = build_attribute(CKA_EXPONENT_2, tmp, len, &e2_attr);
1481 if (rc != CKR_OK) {
1482 TRACE_DEVEL("build_attribute failed\n");
1483 goto cleanup;
1484 }
1485 offset += field_len;
1486 }
1487
1488 // coefficient
1489 //
1490 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
1491 if (rc != CKR_OK) {
1492 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1493 goto cleanup;
1494 } else {
1495 rc = build_attribute(CKA_COEFFICIENT, tmp, len, &coeff_attr);
1496 if (rc != CKR_OK) {
1497 TRACE_DEVEL("build_attribute failed\n");
1498 goto cleanup;
1499 }
1500 offset += len;
1501 }
1502 *priv_exp = d_attr;
1503 *prime1 = p_attr;
1504 *prime2 = q_attr;
1505 *exponent1 = e1_attr;
1506 *exponent2 = e2_attr;
1507 *coeff = coeff_attr;
1508 }
1509
1510 *modulus = n_attr;
1511 *publ_exp = e_attr;
1512
1513 return CKR_OK;
1514
1515 cleanup:
1516 if (n_attr)
1517 free(n_attr);
1518 if (e_attr)
1519 free(e_attr);
1520 if (isopaque) {
1521 if (o_attr)
1522 free(o_attr);
1523 } else {
1524 if (d_attr)
1525 free(d_attr);
1526 if (p_attr)
1527 free(p_attr);
1528 if (q_attr)
1529 free(q_attr);
1530 if (e1_attr)
1531 free(e1_attr);
1532 if (e2_attr)
1533 free(e2_attr);
1534 if (coeff_attr)
1535 free(coeff_attr);
1536 }
1537
1538 return rc;
1539 }
1540
1541
1542 // DSA is a little different from RSA
1543 //
1544 // DSAPrivateKey ::= INTEGER
1545 //
1546 // The 'parameters' field of the AlgorithmIdentifier are as follows:
1547 //
1548 // DSSParameters ::= SEQUENCE {
1549 // prime1 INTEGER
1550 // prime2 INTEGER
1551 // base INTEGER
1552 // }
1553 //
ber_encode_DSAPrivateKey(CK_BBOOL length_only,CK_BYTE ** data,CK_ULONG * data_len,CK_ATTRIBUTE * prime1,CK_ATTRIBUTE * prime2,CK_ATTRIBUTE * base,CK_ATTRIBUTE * priv_key)1554 CK_RV ber_encode_DSAPrivateKey(CK_BBOOL length_only,
1555 CK_BYTE **data,
1556 CK_ULONG *data_len,
1557 CK_ATTRIBUTE *prime1,
1558 CK_ATTRIBUTE *prime2,
1559 CK_ATTRIBUTE *base, CK_ATTRIBUTE *priv_key)
1560 {
1561 CK_BYTE *param = NULL;
1562 CK_BYTE *buf = NULL;
1563 CK_BYTE *tmp = NULL;
1564 CK_BYTE *alg = NULL;
1565 CK_ULONG offset, len, param_len;
1566 CK_ULONG alg_len;
1567 CK_RV rc;
1568
1569
1570 // build the DSS parameters first
1571 //
1572 offset = 0;
1573 rc = 0;
1574
1575 rc |= ber_encode_INTEGER(TRUE, NULL, &len, NULL, prime1->ulValueLen);
1576 offset += len;
1577 rc |= ber_encode_INTEGER(TRUE, NULL, &len, NULL, prime2->ulValueLen);
1578 offset += len;
1579 rc |= ber_encode_INTEGER(TRUE, NULL, &len, NULL, base->ulValueLen);
1580 offset += len;
1581
1582 if (rc != CKR_OK) {
1583 TRACE_DEVEL("ber_encode_INTEGER failed\n");
1584 return CKR_FUNCTION_FAILED;
1585 }
1586 if (length_only == TRUE) {
1587 rc = ber_encode_SEQUENCE(TRUE, NULL, ¶m_len, NULL, offset);
1588 if (rc != CKR_OK) {
1589 TRACE_DEVEL("ber_encode_SEQUENCE failed\n");
1590 return rc;
1591 }
1592 rc = ber_encode_INTEGER(TRUE, NULL, &len, NULL, priv_key->ulValueLen);
1593 if (rc != CKR_OK) {
1594 TRACE_DEVEL("ber_encode_INTEGER failed\n");
1595 return rc;
1596 }
1597 rc = ber_encode_PrivateKeyInfo(TRUE,
1598 NULL, data_len,
1599 NULL, ber_idDSALen + param_len,
1600 NULL, len);
1601 if (rc != CKR_OK) {
1602 TRACE_DEVEL("ber_encode_PrivateKeyInfo failed\n");
1603 }
1604 return rc;
1605 }
1606 // 'buf' will be the sequence data for the AlgorithmIdentifyer::parameter
1607 //
1608 buf = (CK_BYTE *) malloc(offset);
1609 if (!buf) {
1610 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
1611 return CKR_HOST_MEMORY;
1612 }
1613 len = 0;
1614 offset = 0;
1615
1616 rc = ber_encode_INTEGER(FALSE, &tmp, &len,
1617 (CK_BYTE *) prime1 + sizeof(CK_ATTRIBUTE),
1618 prime1->ulValueLen);
1619 if (rc != CKR_OK) {
1620 TRACE_DEVEL("ber_encode_INTEGER failed\n");
1621 goto error;
1622 }
1623 if (tmp != NULL) {
1624 memcpy(buf + offset, tmp, len);
1625 offset += len;
1626 free(tmp);
1627 tmp = NULL;
1628 }
1629
1630 rc = ber_encode_INTEGER(FALSE, &tmp, &len,
1631 (CK_BYTE *) prime2 + sizeof(CK_ATTRIBUTE),
1632 prime2->ulValueLen);
1633 if (rc != CKR_OK) {
1634 TRACE_DEVEL("ber_encode_INTEGER failed\n");
1635 goto error;
1636 }
1637 if (tmp != NULL) {
1638 memcpy(buf + offset, tmp, len);
1639 offset += len;
1640 free(tmp);
1641 tmp = NULL;
1642 }
1643
1644 rc = ber_encode_INTEGER(FALSE, &tmp, &len,
1645 (CK_BYTE *) base + sizeof(CK_ATTRIBUTE),
1646 base->ulValueLen);
1647 if (rc != CKR_OK) {
1648 TRACE_DEVEL("ber_encode_INTEGER failed\n");
1649 goto error;
1650 }
1651 if (tmp != NULL) {
1652 memcpy(buf + offset, tmp, len);
1653 offset += len;
1654 free(tmp);
1655 tmp = NULL;
1656 }
1657
1658 rc = ber_encode_SEQUENCE(FALSE, ¶m, ¶m_len, buf, offset);
1659 if (rc != CKR_OK) {
1660 TRACE_DEVEL("ber_encode_SEQUENCE failed\n");
1661 free(buf);
1662 return rc;
1663 }
1664
1665 free(buf);
1666 buf = NULL;
1667
1668 // Build the DSA AlgorithmIdentifier
1669 //
1670 // AlgorithmIdentifier ::= SEQUENCE {
1671 // algorithm OBJECT IDENTIFIER
1672 // parameters ANY DEFINED BY algorithm OPTIONAL
1673 // }
1674 //
1675 len = ber_idDSALen + param_len;
1676 buf = (CK_BYTE *) malloc(len);
1677 if (!buf) {
1678 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
1679 goto error;
1680 }
1681 memcpy(buf, ber_idDSA, ber_idDSALen);
1682 memcpy(buf + ber_idDSALen, param, param_len);
1683
1684 free(param);
1685 param = NULL;
1686
1687 rc = ber_encode_SEQUENCE(FALSE, &alg, &alg_len, buf, len);
1688 if (rc != CKR_OK) {
1689 TRACE_DEVEL("ber_encode_SEQUENCE failed\n");
1690 goto error;
1691 }
1692 free(buf);
1693 buf = NULL;
1694
1695 // build the private key INTEGER
1696 //
1697 rc = ber_encode_INTEGER(FALSE, &buf, &len,
1698 (CK_BYTE *) priv_key + sizeof(CK_ATTRIBUTE),
1699 priv_key->ulValueLen);
1700 if (rc != CKR_OK) {
1701 TRACE_DEVEL("ber_encode_INTEGER failed\n");
1702 goto error;
1703 }
1704
1705 rc = ber_encode_PrivateKeyInfo(FALSE,
1706 data, data_len, alg, alg_len, buf, len);
1707 if (rc != CKR_OK) {
1708 TRACE_DEVEL("ber_encode_PrivateKeyInfo failed\n");
1709 goto error;
1710 }
1711
1712 error:
1713 if (alg)
1714 free(alg);
1715 if (buf)
1716 free(buf);
1717 if (param)
1718 free(param);
1719 if (tmp)
1720 free(tmp);
1721
1722 return rc;
1723 }
1724
1725
1726 //
1727 //
ber_decode_DSAPrivateKey(CK_BYTE * data,CK_ULONG data_len,CK_ATTRIBUTE ** prime,CK_ATTRIBUTE ** subprime,CK_ATTRIBUTE ** base,CK_ATTRIBUTE ** priv_key)1728 CK_RV ber_decode_DSAPrivateKey(CK_BYTE *data,
1729 CK_ULONG data_len,
1730 CK_ATTRIBUTE **prime,
1731 CK_ATTRIBUTE **subprime,
1732 CK_ATTRIBUTE **base, CK_ATTRIBUTE **priv_key)
1733 {
1734 CK_ATTRIBUTE *p_attr = NULL;
1735 CK_ATTRIBUTE *q_attr = NULL;
1736 CK_ATTRIBUTE *g_attr = NULL;
1737 CK_ATTRIBUTE *x_attr = NULL;
1738 CK_BYTE *alg = NULL;
1739 CK_BYTE *buf = NULL;
1740 CK_BYTE *dsakey = NULL;
1741 CK_BYTE *tmp = NULL;
1742 CK_ULONG buf_len, field_len, len, offset;
1743 CK_RV rc;
1744
1745
1746 rc = ber_decode_PrivateKeyInfo(data, data_len, &alg, &len, &dsakey);
1747 if (rc != CKR_OK) {
1748 TRACE_DEVEL("ber_decode_PrivateKeyInfo failed\n");
1749 return rc;
1750 }
1751 // make sure we're dealing with a DSA key. just compare the OBJECT
1752 // IDENTIFIER
1753 //
1754 if (memcmp(alg, ber_idDSA, ber_idDSALen) != 0) {
1755 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
1756 return CKR_FUNCTION_FAILED;
1757 }
1758 // extract the parameter data into ATTRIBUTES
1759 //
1760 rc = ber_decode_SEQUENCE(alg + ber_idDSALen, &buf, &buf_len, &field_len);
1761 if (rc != CKR_OK) {
1762 TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
1763 return rc;
1764 }
1765 offset = 0;
1766
1767 // prime
1768 //
1769 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
1770 if (rc != CKR_OK) {
1771 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1772 goto cleanup;
1773 }
1774 offset += field_len;
1775
1776 // subprime
1777 //
1778 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
1779 if (rc != CKR_OK) {
1780 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1781 goto cleanup;
1782 }
1783 offset += field_len;
1784
1785 // base
1786 //
1787 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
1788 if (rc != CKR_OK) {
1789 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1790 goto cleanup;
1791 }
1792 offset += field_len;
1793
1794 if (offset > buf_len) {
1795 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
1796 return CKR_FUNCTION_FAILED;
1797 }
1798 //
1799 // it looks okay. build the attributes
1800 //
1801
1802 offset = 0;
1803
1804 // prime
1805 //
1806 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
1807 if (rc != CKR_OK) {
1808 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1809 goto cleanup;
1810 } else {
1811 rc = build_attribute(CKA_PRIME, tmp, len, &p_attr);
1812 if (rc != CKR_OK) {
1813 TRACE_DEVEL("build_attribute failed\n");
1814 goto cleanup;
1815 }
1816 offset += field_len;
1817 }
1818
1819 // subprime
1820 //
1821 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
1822 if (rc != CKR_OK) {
1823 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1824 goto cleanup;
1825 } else {
1826 rc = build_attribute(CKA_SUBPRIME, tmp, len, &q_attr);
1827 if (rc != CKR_OK) {
1828 TRACE_DEVEL("build_attribute failed\n");
1829 goto cleanup;
1830 }
1831 offset += field_len;
1832 }
1833
1834 // base
1835 //
1836 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
1837 if (rc != CKR_OK) {
1838 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1839 goto cleanup;
1840 } else {
1841 rc = build_attribute(CKA_BASE, tmp, len, &g_attr);
1842 if (rc != CKR_OK) {
1843 TRACE_DEVEL("build_attribute failed\n");
1844 goto cleanup;
1845 }
1846 offset += field_len;
1847 }
1848
1849 // now get the private key
1850 //
1851 rc = ber_decode_INTEGER(dsakey, &tmp, &len, &field_len);
1852 if (rc != CKR_OK) {
1853 TRACE_DEVEL("ber_decode_INTEGER failed\n");
1854 goto cleanup;
1855 } else {
1856 rc = build_attribute(CKA_VALUE, tmp, len, &x_attr);
1857 if (rc != CKR_OK) {
1858 TRACE_DEVEL("build_attribute failed\n");
1859 goto cleanup;
1860 }
1861 offset += field_len;
1862 }
1863
1864 *prime = p_attr;
1865 *subprime = q_attr;
1866 *base = g_attr;
1867 *priv_key = x_attr;
1868
1869 return CKR_OK;
1870
1871 cleanup:
1872 if (p_attr)
1873 free(p_attr);
1874 if (q_attr)
1875 free(q_attr);
1876 if (g_attr)
1877 free(g_attr);
1878 if (x_attr)
1879 free(x_attr);
1880
1881 return rc;
1882 }
1883
1884 /*
1885 * ECC Functions
1886 */
1887 //
1888 //
ecdsa_priv_unwrap_get_data(TEMPLATE * tmpl,CK_BYTE * data,CK_ULONG total_length)1889 CK_RV ecdsa_priv_unwrap_get_data(TEMPLATE *tmpl,
1890 CK_BYTE *data, CK_ULONG total_length)
1891 {
1892 CK_ATTRIBUTE *params = NULL;
1893 CK_ATTRIBUTE *point = NULL;
1894 CK_RV rc;
1895
1896 rc = der_decode_ECPublicKey(data, total_length, ¶ms, &point);
1897
1898 if (rc != CKR_OK) {
1899 TRACE_DEVEL("ber_decode_ECPrivateKey failed\n");
1900 return rc;
1901 }
1902
1903 p11_attribute_trim(params);
1904 p11_attribute_trim(point);
1905
1906 rc = template_update_attribute(tmpl, params);
1907 if (rc != CKR_OK)
1908 TRACE_DEVEL("template_update_attribute(CKA_EC_PARAMS) failed\n");
1909 rc = template_update_attribute(tmpl, point);
1910 if (rc != CKR_OK)
1911 TRACE_DEVEL("template_update_attribute(CKA_EC_POINT) failed\n");
1912
1913 return CKR_OK;
1914 }
1915
1916
1917 //
1918 //
der_encode_ECPrivateKey(CK_BBOOL length_only,CK_BYTE ** data,CK_ULONG * data_len,CK_ATTRIBUTE * params,CK_ATTRIBUTE * point,CK_ATTRIBUTE * opaque,CK_ATTRIBUTE * pubkey)1919 CK_RV der_encode_ECPrivateKey(CK_BBOOL length_only,
1920 CK_BYTE **data,
1921 CK_ULONG *data_len,
1922 CK_ATTRIBUTE *params,
1923 CK_ATTRIBUTE *point,
1924 CK_ATTRIBUTE *opaque, CK_ATTRIBUTE *pubkey)
1925 {
1926 CK_BYTE *buf = NULL;
1927 CK_BYTE *buf2 = NULL;
1928 CK_ULONG len, offset = 0;
1929 CK_BYTE version[] = { 1 }; // ecPrivkeyVer1
1930 CK_BYTE der_AlgIdEC[der_AlgIdECBaseLen + params->ulValueLen];
1931 CK_ULONG der_AlgIdECLen = sizeof(der_AlgIdEC);
1932 BerElement *ber;
1933 BerValue *val;
1934 CK_RV rc = 0;
1935
1936 /* Calculate BER encoding length
1937 * Inner SEQUENCE of
1938 * Integer (version), OCTET STRING (private key)
1939 * and CHOICE [1] BIT STRING (public key)
1940 */
1941 // version
1942 rc |= ber_encode_INTEGER(TRUE, NULL, &len, NULL, sizeof(version));
1943 offset += len;
1944
1945 // private key octet
1946 if (opaque != NULL) {
1947 rc |= ber_encode_OCTET_STRING(TRUE, NULL, &len, NULL,
1948 opaque->ulValueLen);
1949 offset += len;
1950 } else {
1951 rc |= ber_encode_OCTET_STRING(TRUE, NULL, &len, NULL,
1952 point->ulValueLen);
1953 offset += len;
1954 }
1955 if (rc != CKR_OK) {
1956 TRACE_DEVEL("der encoding failed\n");
1957 return CKR_FUNCTION_FAILED;
1958 }
1959 // public key bit string
1960 if (pubkey && pubkey->pValue) {
1961 ber = ber_alloc_t(LBER_USE_DER);
1962 rc = ber_put_bitstring(ber, pubkey->pValue,
1963 pubkey->ulValueLen * 8, 0x03);
1964 rc = ber_flatten(ber, &val);
1965
1966 ber_encode_CHOICE(TRUE, 1, &buf2, &len, (CK_BYTE *)val->bv_val,
1967 val->bv_len);
1968 offset += len;
1969 ber_free(ber, 1);
1970 }
1971
1972 if (length_only == TRUE) {
1973 rc = ber_encode_SEQUENCE(TRUE, NULL, &len, NULL, offset);
1974 if (rc != CKR_OK) {
1975 TRACE_DEVEL("ber_encode_SEQUENCE failed\n");
1976 return rc;
1977 }
1978 rc = ber_encode_PrivateKeyInfo(TRUE, NULL, data_len, NULL,
1979 der_AlgIdECLen, NULL, len);
1980 if (rc != CKR_OK) {
1981 TRACE_DEVEL("ber_encode_PrivateKeyInfo failed\n");
1982 return rc;
1983 }
1984 return rc;
1985 }
1986
1987 /* Now starting with the real data */
1988 buf = (CK_BYTE *) malloc(offset);
1989 if (!buf) {
1990 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
1991 return CKR_HOST_MEMORY;
1992 }
1993 offset = 0;
1994 rc = 0;
1995
1996 rc = ber_encode_INTEGER(FALSE, &buf2, &len, version, sizeof(version));
1997 if (rc != CKR_OK) {
1998 TRACE_DEVEL("ber_encode_INTEGER failed\n");
1999 goto error;
2000 }
2001 if (buf2 != NULL) {
2002 memcpy(buf + offset, buf2, len);
2003 offset += len;
2004 free(buf2);
2005 buf2 = NULL;
2006 }
2007
2008 if (opaque != NULL) {
2009 // the CKA_IBM_OPAQUE attrib
2010 rc = ber_encode_OCTET_STRING(FALSE, &buf2, &len,
2011 (CK_BYTE *) opaque +
2012 sizeof(CK_ATTRIBUTE), opaque->ulValueLen);
2013 if (rc != CKR_OK) {
2014 TRACE_DEVEL("ber_encode_OCTET_STRING failed\n");
2015 goto error;
2016 }
2017 memcpy(buf + offset, buf2, len);
2018 offset += len;
2019 free(buf2);
2020 buf2 = NULL;
2021 } else {
2022 rc = ber_encode_OCTET_STRING(FALSE, &buf2, &len,
2023 (CK_BYTE *) point +
2024 sizeof(CK_ATTRIBUTE), point->ulValueLen);
2025 if (rc != CKR_OK) {
2026 TRACE_DEVEL("ber_encode_INTEGER failed\n");
2027 goto error;
2028 }
2029 if (buf2 != NULL) {
2030 memcpy(buf + offset, buf2, len);
2031 offset += len;
2032 free(buf2);
2033 buf2 = NULL;
2034 }
2035 }
2036
2037 /* generate optional bit-string of public key */
2038 if (pubkey && pubkey->pValue) {
2039 ber = ber_alloc_t(LBER_USE_DER);
2040 rc = ber_put_bitstring(ber, pubkey->pValue,
2041 pubkey->ulValueLen * 8, 0x03);
2042 rc = ber_flatten(ber, &val);
2043
2044 ber_encode_CHOICE(FALSE, 1, &buf2, &len, (CK_BYTE *)val->bv_val,
2045 val->bv_len);
2046 memcpy(buf + offset, buf2, len);
2047 offset += len;
2048 free(buf2);
2049 buf2 = NULL;
2050 ber_free(ber, 1);
2051 }
2052
2053 rc = ber_encode_SEQUENCE(FALSE, &buf2, &len, buf, offset);
2054 if (rc != CKR_OK) {
2055 TRACE_DEVEL("ber_encode_SEQUENCE failed\n");
2056 goto error;
2057 }
2058
2059 /* concatenate EC algorithm-id + specific curve id */
2060 memcpy(der_AlgIdEC, der_AlgIdECBase, der_AlgIdECBaseLen);
2061 memcpy(der_AlgIdEC + der_AlgIdECBaseLen, params->pValue,
2062 params->ulValueLen);
2063 /* adjust length field */
2064 der_AlgIdEC[1] = der_AlgIdEC[1] + params->ulValueLen;
2065
2066 rc = ber_encode_PrivateKeyInfo(FALSE, data, data_len, der_AlgIdEC,
2067 der_AlgIdECLen, buf2, len);
2068 if (rc != CKR_OK) {
2069 TRACE_ERROR("ber_encode_PrivateKeyInfo failed\n");
2070 }
2071
2072 error:
2073 if (buf2)
2074 free(buf2);
2075 if (buf)
2076 free(buf);
2077
2078 return rc;
2079 }
2080
2081 //
2082 // From RFC 5915:
2083 //
2084 // ECPrivateKey ::= SEQUENCE {
2085 // version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
2086 // privateKey OCTET STRING,
2087 // parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
2088 // publicKey [1] BIT STRING OPTIONAL
2089 // }
2090 //
der_decode_ECPrivateKey(CK_BYTE * data,CK_ULONG data_len,CK_ATTRIBUTE ** params,CK_ATTRIBUTE ** pub_key,CK_ATTRIBUTE ** priv_key,CK_ATTRIBUTE ** opaque_key,CK_BBOOL isOpaque)2091 CK_RV der_decode_ECPrivateKey(CK_BYTE *data,
2092 CK_ULONG data_len,
2093 CK_ATTRIBUTE **params,
2094 CK_ATTRIBUTE **pub_key,
2095 CK_ATTRIBUTE **priv_key,
2096 CK_ATTRIBUTE **opaque_key, CK_BBOOL isOpaque)
2097 {
2098 CK_ATTRIBUTE *pub_attr = NULL;
2099 CK_ATTRIBUTE *priv_attr = NULL;
2100 CK_ATTRIBUTE *opaque_attr = NULL;
2101 CK_ATTRIBUTE *parm_attr = NULL;
2102 CK_BYTE *alg = NULL;
2103 CK_BYTE *buf = NULL;
2104 CK_BYTE *priv_buf = NULL;
2105 CK_BYTE *pub_buf = NULL;
2106 CK_BYTE *parm_buf = NULL;
2107 CK_BYTE *eckey = NULL;
2108 CK_BYTE *version = NULL;
2109 CK_BYTE *choice = NULL;
2110 CK_ULONG version_len, alg_len, priv_len, pub_len, parm_len, buf_len;
2111 CK_ULONG buf_offset, field_len, offset, choice_len, option;
2112 CK_ULONG pubkey_available = 0;
2113 CK_RV rc;
2114
2115
2116 /* Decode PrivateKeyInfo into alg and eckey */
2117 rc = ber_decode_PrivateKeyInfo(data, data_len, &alg, &alg_len, &eckey);
2118 if (rc != CKR_OK) {
2119 TRACE_DEVEL("ber_decode_PrivateKeyInfo failed\n");
2120 return rc;
2121 }
2122
2123 /* Check OBJECT IDENTIFIER to make sure this is an EC key */
2124 if (memcmp(alg, ber_idEC, ber_idECLen) != 0) {
2125 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2126 return CKR_FUNCTION_FAILED;
2127 }
2128
2129 /* Decode the ecdhkey into buf */
2130 rc = ber_decode_SEQUENCE(eckey, &buf, &buf_len, &field_len);
2131 if (rc != CKR_OK) {
2132 TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
2133 return rc;
2134 }
2135 offset = 0;
2136
2137 /* Decode version (INTEGER) */
2138 rc = ber_decode_INTEGER(buf + offset, &version, &version_len, &field_len);
2139 if (rc != CKR_OK) {
2140 TRACE_DEVEL("ber_decode_INTEGER failed\n");
2141 goto cleanup;
2142 }
2143 offset += field_len;
2144
2145 /* Decode private key (OCTET_STRING) */
2146 rc = ber_decode_OCTET_STRING(buf + offset, &priv_buf, &priv_len,
2147 &field_len);
2148 if (rc != CKR_OK) {
2149 TRACE_DEVEL("ber_decode_OCTET_STRING failed\n");
2150 goto cleanup;
2151 }
2152 offset += field_len;
2153
2154 /* Check if there is an optional public key */
2155 buf_offset = buf - data;
2156 if (buf_offset + offset < data_len) {
2157
2158 /* Decode CHOICE */
2159 rc = ber_decode_CHOICE(buf + offset, &choice, &choice_len, &field_len,
2160 &option);
2161 if (rc != CKR_OK) {
2162 TRACE_DEVEL("ber_decode_CHOICE failed\n");
2163 goto cleanup;
2164 }
2165 offset += field_len - choice_len;
2166
2167 /* Decode public key (BIT_STRING) according to option */
2168 switch (option) {
2169 case 0:
2170 /* parameters [0] ECParameters {{ NamedCurve }} OPTIONAL
2171 * These params, if available, are assumed to be the same as algo
2172 * above, so nothing to do here.
2173 */
2174 break;
2175 case 1:
2176 /* publicKey [1] BIT STRING OPTIONAL */
2177 rc = ber_decode_BIT_STRING(buf + offset, &pub_buf, &pub_len,
2178 &field_len);
2179 if (rc != CKR_OK) {
2180 TRACE_DEVEL("ber_decode_BIT_STRING failed\n");
2181 goto cleanup;
2182 }
2183 pubkey_available = 1;
2184 break;
2185 default:
2186 TRACE_DEVEL("ber_decode_CHOICE returned invalid or unsupported "
2187 "option %ld\n", option);
2188 goto cleanup;
2189 }
2190 }
2191
2192 /* Now build attribute for CKA_ECDSA_PARAMS */
2193 parm_buf = alg + ber_idECLen;
2194 parm_len = alg_len - ber_idECLen;
2195 rc = build_attribute(CKA_ECDSA_PARAMS, parm_buf, parm_len, &parm_attr);
2196 if (rc != CKR_OK) {
2197 TRACE_DEVEL("build_attribute for CKA_ECDSA_PARAMS failed\n");
2198 goto cleanup;
2199 }
2200
2201 /* Build attr for public key */
2202 if (pubkey_available) {
2203 rc = build_attribute(CKA_EC_POINT, pub_buf, pub_len, &pub_attr);
2204 if (rc != CKR_OK) {
2205 TRACE_DEVEL("build_attribute for public key failed\n");
2206 goto cleanup;
2207 }
2208 }
2209
2210 /* Build attr for private key */
2211 if (isOpaque) {
2212 rc = build_attribute(CKA_IBM_OPAQUE, priv_buf, priv_len, &opaque_attr);
2213 if (rc != CKR_OK) {
2214 TRACE_DEVEL("build_attribute for private key failed\n");
2215 goto cleanup;
2216 }
2217 } else {
2218 rc = build_attribute(CKA_VALUE, priv_buf, priv_len, &priv_attr);
2219 if (rc != CKR_OK) {
2220 TRACE_DEVEL("build_attribute for private key failed\n");
2221 goto cleanup;
2222 }
2223 }
2224
2225 *pub_key = pub_attr; // may be NULL if no BIT_STRING available
2226 *priv_key = priv_attr; // may be NULL if key is opaque
2227 *opaque_key = opaque_attr;
2228 *params = parm_attr;
2229
2230 return CKR_OK;
2231
2232 cleanup:
2233 if (pub_attr)
2234 free(pub_attr);
2235 if (priv_attr)
2236 free(priv_attr);
2237 if (opaque_attr)
2238 free(opaque_attr);
2239 if (parm_attr)
2240 free(parm_attr);
2241
2242 return rc;
2243 }
2244
2245 /*
2246 * ASN.1 type PrivateKeyInfo ::= SEQUENCE {
2247 * version Version
2248 * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier
2249 * privateKey PrivateKey
2250 * attributes OPTIONAL
2251 * }
2252 *
2253 * Where PrivateKey is defined as follows for EC:
2254 *
2255 * ASN.1 type RSAPrivateKey
2256 *
2257 * ECPrivateKey ::= SEQUENCE {
2258 * version Version
2259 * privateKey OCTET STRING
2260 * parameters [0] ECParameters (OPTIONAL)
2261 * publicKey [1] BIT STRING (OPTIONAL)
2262 * }
2263 */
der_decode_ECPublicKey(CK_BYTE * data,CK_ULONG data_len,CK_ATTRIBUTE ** ec_params,CK_ATTRIBUTE ** ec_point)2264 CK_RV der_decode_ECPublicKey(CK_BYTE *data,
2265 CK_ULONG data_len,
2266 CK_ATTRIBUTE **ec_params,
2267 CK_ATTRIBUTE **ec_point)
2268 {
2269 CK_ATTRIBUTE *params_attr = NULL;
2270 CK_ATTRIBUTE *point_attr = NULL;
2271
2272 CK_BYTE *inner_seq = NULL;
2273 CK_BYTE *algid = NULL;
2274 CK_ULONG algid_len;
2275 CK_BYTE *algid_ECBase = NULL;
2276 CK_BYTE *param = NULL;
2277 CK_ULONG param_len;
2278 CK_BYTE *point = NULL;
2279 CK_ULONG point_len;
2280 CK_ULONG offset = 0;
2281 CK_ULONG field_len, len;
2282 CK_RV rc;
2283
2284 UNUSED(data_len); // XXX can this parameter be removed ?
2285
2286 rc = ber_decode_SEQUENCE(data, &inner_seq, &len, &field_len);
2287 if (rc != CKR_OK) {
2288 TRACE_DEVEL("ber_decode_PrivateKeyInfo failed\n");
2289 return rc;
2290 }
2291
2292 rc = ber_decode_SEQUENCE(inner_seq, &algid, &algid_len, &field_len);
2293 if (rc != CKR_OK) {
2294 TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
2295 return rc;
2296 }
2297 offset += field_len;
2298
2299 /*
2300 * Make sure we're dealing with an EC key.
2301 * Extract base alg-id of DER encoded EC byte string
2302 * and compare against the decoded alg-id from the inner sequence
2303 */
2304 rc = ber_decode_SEQUENCE(der_AlgIdECBase, &algid_ECBase, &len, &field_len);
2305 if (rc != CKR_OK) {
2306 TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
2307 return rc;
2308 }
2309
2310 if (memcmp(algid, algid_ECBase, len) != 0) {
2311 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2312 return CKR_FUNCTION_FAILED;
2313 }
2314
2315 /* skip the generic EC publ key ID and
2316 * point to the curve specific parameter
2317 */
2318 param = algid + algid[1] + 2;
2319 param_len = algid_len - algid[1] - 2;
2320
2321 rc = ber_decode_BIT_STRING(inner_seq + offset, &point, &point_len,
2322 &field_len);
2323 if (rc != CKR_OK) {
2324 TRACE_DEVEL("ber_decode_OCTET_STRING failed\n");
2325 goto cleanup;
2326 }
2327 // build ec-parameter attribute
2328 rc = build_attribute(CKA_EC_PARAMS, param, param_len, ¶ms_attr);
2329 if (rc != CKR_OK) {
2330 TRACE_DEVEL("build_attribute failed\n");
2331 goto cleanup;
2332 }
2333 // build ec-point attribute
2334 rc = build_attribute(CKA_EC_POINT, point, point_len, &point_attr);
2335 if (rc != CKR_OK) {
2336 TRACE_DEVEL("build_attribute failed\n");
2337 goto cleanup;
2338 }
2339
2340 *ec_params = params_attr;
2341 *ec_point = point_attr;
2342 return CKR_OK;
2343
2344 cleanup:
2345 if (params_attr)
2346 free(params_attr);
2347 if (point_attr)
2348 free(point_attr);
2349
2350 return rc;
2351 }
2352
2353 // DH is a little different from RSA
2354 //
2355 // DHPrivateKey ::= INTEGER
2356 //
2357 // The 'parameters' field of the AlgorithmIdentifier are as follows:
2358 //
2359 // DSSParameters ::= SEQUENCE {
2360 // prime INTEGER
2361 // base INTEGER
2362 // }
2363 //
ber_encode_DHPrivateKey(CK_BBOOL length_only,CK_BYTE ** data,CK_ULONG * data_len,CK_ATTRIBUTE * prime,CK_ATTRIBUTE * base,CK_ATTRIBUTE * priv_key)2364 CK_RV ber_encode_DHPrivateKey(CK_BBOOL length_only,
2365 CK_BYTE **data,
2366 CK_ULONG *data_len,
2367 CK_ATTRIBUTE *prime,
2368 CK_ATTRIBUTE *base, CK_ATTRIBUTE *priv_key)
2369 {
2370 CK_BYTE *param = NULL;
2371 CK_BYTE *buf = NULL;
2372 CK_BYTE *tmp = NULL;
2373 CK_BYTE *alg = NULL;
2374 CK_ULONG offset, len, param_len;
2375 CK_ULONG alg_len;
2376 CK_RV rc;
2377
2378 // build the DSS parameters first
2379 offset = 0;
2380 rc = 0;
2381
2382 rc |= ber_encode_INTEGER(TRUE, NULL, &len, NULL, prime->ulValueLen);
2383 offset += len;
2384 rc |= ber_encode_INTEGER(TRUE, NULL, &len, NULL, base->ulValueLen);
2385 offset += len;
2386
2387 if (rc != CKR_OK) {
2388 TRACE_DEVEL("ber_encode_INTEGER failed\n");
2389 return CKR_FUNCTION_FAILED;
2390 }
2391 if (length_only == TRUE) {
2392 rc = ber_encode_SEQUENCE(TRUE, NULL, ¶m_len, NULL, offset);
2393 if (rc != CKR_OK) {
2394 TRACE_DEVEL("ber_encode_SEQUENCE failed\n");
2395 return rc;
2396 }
2397 rc = ber_encode_INTEGER(TRUE, NULL, &len, NULL, priv_key->ulValueLen);
2398 if (rc != CKR_OK) {
2399 TRACE_DEVEL("ber_encode_INTEGER failed\n");
2400 return rc;
2401 }
2402 rc = ber_encode_PrivateKeyInfo(TRUE,
2403 NULL, data_len,
2404 NULL, ber_idDHLen + param_len,
2405 NULL, len);
2406 if (rc != CKR_OK) {
2407 TRACE_DEVEL("ber_encode_PrivateKeyInfo failed\n");
2408 }
2409 return rc;
2410 }
2411 // 'buf' will be the sequence data for the AlgorithmIdentifyer::parameter
2412 buf = (CK_BYTE *) malloc(offset);
2413 if (!buf) {
2414 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2415 return CKR_HOST_MEMORY;
2416 }
2417 len = 0;
2418 offset = 0;
2419
2420 rc = ber_encode_INTEGER(FALSE, &tmp, &len, prime->pValue,
2421 prime->ulValueLen);
2422 if (rc != CKR_OK) {
2423 TRACE_DEVEL("ber_encode_INTEGER failed\n");
2424 goto error;
2425 }
2426 if (tmp != NULL) {
2427 memcpy(buf + offset, tmp, len);
2428 offset += len;
2429 free(tmp);
2430 tmp = NULL;
2431 }
2432
2433 rc = ber_encode_INTEGER(FALSE, &tmp, &len, base->pValue, base->ulValueLen);
2434 if (rc != CKR_OK) {
2435 TRACE_DEVEL("ber_encode_INTEGER failed\n");
2436 goto error;
2437 }
2438 if (tmp != NULL) {
2439 memcpy(buf + offset, tmp, len);
2440 offset += len;
2441 free(tmp);
2442 tmp = NULL;
2443 }
2444
2445 rc = ber_encode_SEQUENCE(FALSE, ¶m, ¶m_len, buf, offset);
2446 if (rc != CKR_OK) {
2447 TRACE_DEVEL("ber_encode_SEQUENCE failed\n");
2448 free(buf);
2449 return rc;
2450 }
2451
2452 free(buf);
2453 buf = NULL;
2454
2455 // Build the DSA AlgorithmIdentifier
2456 //
2457 // AlgorithmIdentifier ::= SEQUENCE {
2458 // algorithm OBJECT IDENTIFIER
2459 // parameters ANY DEFINED BY algorithm OPTIONAL
2460 // }
2461 //
2462 len = ber_idDHLen + param_len;
2463 buf = (CK_BYTE *) malloc(len);
2464 if (!buf) {
2465 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
2466 goto error;
2467 }
2468 memcpy(buf, ber_idDH, ber_idDHLen);
2469 memcpy(buf + ber_idDHLen, param, param_len);
2470
2471 free(param);
2472 param = NULL;
2473
2474 rc = ber_encode_SEQUENCE(FALSE, &alg, &alg_len, buf, len);
2475 if (rc != CKR_OK) {
2476 TRACE_DEVEL("ber_encode_SEQUENCE failed\n");
2477 goto error;
2478 }
2479 free(buf);
2480 buf = NULL;
2481
2482 // build the private key INTEGER
2483 rc = ber_encode_INTEGER(FALSE, &buf, &len, priv_key->pValue,
2484 priv_key->ulValueLen);
2485 if (rc != CKR_OK) {
2486 TRACE_DEVEL("ber_encode_INTEGER failed\n");
2487 goto error;
2488 }
2489
2490 rc = ber_encode_PrivateKeyInfo(FALSE,
2491 data, data_len, alg, alg_len, buf, len);
2492 if (rc != CKR_OK) {
2493 TRACE_DEVEL("ber_encode_PrivateKeyInfo failed\n");
2494 goto error;
2495 }
2496
2497 error:
2498 if (alg)
2499 free(alg);
2500 if (buf)
2501 free(buf);
2502 if (param)
2503 free(param);
2504 if (tmp)
2505 free(tmp);
2506
2507 return rc;
2508 }
2509
2510 //
2511 //
ber_decode_DHPrivateKey(CK_BYTE * data,CK_ULONG data_len,CK_ATTRIBUTE ** prime,CK_ATTRIBUTE ** base,CK_ATTRIBUTE ** priv_key)2512 CK_RV ber_decode_DHPrivateKey(CK_BYTE *data,
2513 CK_ULONG data_len,
2514 CK_ATTRIBUTE **prime,
2515 CK_ATTRIBUTE **base, CK_ATTRIBUTE **priv_key)
2516 {
2517 CK_ATTRIBUTE *p_attr = NULL;
2518 CK_ATTRIBUTE *g_attr = NULL;
2519 CK_ATTRIBUTE *x_attr = NULL;
2520 CK_BYTE *alg = NULL;
2521 CK_BYTE *buf = NULL;
2522 CK_BYTE *dhkey = NULL;
2523 CK_BYTE *tmp = NULL;
2524 CK_ULONG buf_len, field_len, len, offset;
2525 CK_RV rc;
2526
2527 rc = ber_decode_PrivateKeyInfo(data, data_len, &alg, &len, &dhkey);
2528 if (rc != CKR_OK) {
2529 TRACE_DEVEL("ber_decode_PrivateKeyInfo failed\n");
2530 return rc;
2531 }
2532 // make sure we're dealing with a DH key. just compare the OBJECT
2533 // IDENTIFIER
2534 if (memcmp(alg, ber_idDH, ber_idDHLen) != 0) {
2535 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2536 return CKR_FUNCTION_FAILED;
2537 }
2538 // extract the parameter data into ATTRIBUTES
2539 //
2540 rc = ber_decode_SEQUENCE(alg + ber_idDSALen, &buf, &buf_len, &field_len);
2541 if (rc != CKR_OK) {
2542 TRACE_DEVEL("ber_decode_SEQUENCE failed\n");
2543 return rc;
2544 }
2545 offset = 0;
2546
2547 // prime
2548 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
2549 if (rc != CKR_OK) {
2550 TRACE_DEVEL("ber_decode_INTEGER failed\n");
2551 goto cleanup;
2552 }
2553 offset += field_len;
2554
2555 // base
2556 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
2557 if (rc != CKR_OK) {
2558 TRACE_DEVEL("ber_decode_INTEGER failed\n");
2559 goto cleanup;
2560 }
2561 offset += field_len;
2562
2563 if (offset > buf_len) {
2564 TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
2565 return CKR_FUNCTION_FAILED;
2566 }
2567 // it looks okay. build the attributes
2568
2569 offset = 0;
2570
2571 // prime
2572 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
2573 if (rc != CKR_OK) {
2574 TRACE_DEVEL("ber_decode_INTEGER failed\n");
2575 goto cleanup;
2576 } else {
2577 rc = build_attribute(CKA_PRIME, tmp, len, &p_attr);
2578 if (rc != CKR_OK) {
2579 TRACE_DEVEL("build_attribute failed\n");
2580 goto cleanup;
2581 }
2582 offset += field_len;
2583 }
2584
2585 // base
2586 rc = ber_decode_INTEGER(buf + offset, &tmp, &len, &field_len);
2587 if (rc != CKR_OK) {
2588 TRACE_DEVEL("ber_decode_INTEGER failed\n");
2589 goto cleanup;
2590 } else {
2591 rc = build_attribute(CKA_BASE, tmp, len, &g_attr);
2592 if (rc != CKR_OK) {
2593 TRACE_DEVEL("build_attribute failed\n");
2594 goto cleanup;
2595 }
2596 offset += field_len;
2597 }
2598
2599 // now get the private key
2600 rc = ber_decode_INTEGER(dhkey, &tmp, &len, &field_len);
2601 if (rc != CKR_OK) {
2602 TRACE_DEVEL("ber_decode_INTEGER failed\n");
2603 goto cleanup;
2604 } else {
2605 rc = build_attribute(CKA_VALUE, tmp, len, &x_attr);
2606 if (rc != CKR_OK) {
2607 TRACE_DEVEL("build_attribute failed\n");
2608 goto cleanup;
2609 }
2610 offset += field_len;
2611 }
2612
2613 *prime = p_attr;
2614 *base = g_attr;
2615 *priv_key = x_attr;
2616
2617 return CKR_OK;
2618
2619 cleanup:
2620 if (p_attr)
2621 free(p_attr);
2622 if (g_attr)
2623 free(g_attr);
2624 if (x_attr)
2625 free(x_attr);
2626
2627 return rc;
2628 }
2629