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, &param_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, &param, &param_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, &params, &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, &params_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, &param_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, &param, &param_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