1 /*
2  * Copyright (c) 2021 Mastercard
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /* attribctx attributes parser */
18 %define api.prefix {cl}
19 %define parse.error verbose
20 %define parse.trace
21 /* %define lr.type canonical-lr */
22 
23 %code top {
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 }
28 
29 
30 %code requires {
31 #include "pkcs11lib.h"
32 #include "attribctx_helper.h"
33 }
34 
35 %code provides {
36 #define YY_DECL int yylex(attribCtx* ctx)
37 
38 YY_DECL;
39 extern void clerror(attribCtx *ctx, const char *s, ...);
40 
41 }
42 
43 %param { attribCtx *ctx }
44 
45 
46 %union {
47     CK_ATTRIBUTE_TYPE ckattr;
48     CK_KEY_TYPE val_key;
49     CK_OBJECT_CLASS val_cls;
50     CK_BBOOL val_bool;
51     CK_MECHANISM_TYPE val_mech;
52 
53     struct {			/* HEX encoded - or real string */
54 	char *val;
55 	size_t len;
56 	} val_str;
57 
58     union {
59 	struct {
60 	    char year[4];
61 	    char month[2];
62 	    char day[2];
63 	} as_ck_date;
64         char as_buffer[8];
65     } val_date;
66 }
67 
68 /* declare tokens */
69 %token <val_str> STRING
70 
71 %token <ckattr> CKATTR_BOOL CKATTR_STR CKATTR_DATE CKATTR_KEY CKATTR_CLASS CKATTR_TEMPLATE CKATTR_ALLOWEDMECH
72 %token <val_mech> CKMECH
73 %token <val_bool> TOK_BOOLEAN
74 %token <val_date> TOK_DATE
75 %token <val_key>  KEYTYPE
76 %token <val_cls>  OCLASS
77 %nonassoc NO
78 %token ASSIGN CURLY_OPEN CURLY_CLOSE
79 
80 %%
81 
82 /* cmdline is used to parse the command line
83  * we artifically expect to have a front "#" character
84  * so we know we are in this parsing job
85  */
86 
87 statement:	expression
88 	|       statement expression
89 	;
90 
91 expression:	simple_expr
92 	|	template_expr
93 	|	allowedmech_expr
94 	;
95 
96 simple_expr:	CKATTR_BOOL ASSIGN TOK_BOOLEAN
97                 {
98 		    if(_attribctx_parser_append_attr(ctx, $1, &$3, sizeof(CK_BBOOL) )!=rc_ok) {
99 			clerror(ctx,"Error during parsing, cannot assign boolean value.");
100 			YYERROR;
101 		    }
102 		}
103 	|	NO CKATTR_BOOL
104                 {
105 		    CK_BBOOL bfalse = CK_FALSE;
106 
107 		    if(_attribctx_parser_append_attr(ctx, $2, &bfalse, sizeof(CK_BBOOL) )!=rc_ok) {
108 			clerror(ctx,"Error during parsing, cannot assign boolean value.");
109 			YYERROR;
110 		    }
111 		}
112 	|	CKATTR_BOOL
113                 {
114 		    CK_BBOOL btrue = CK_TRUE;
115 
116 		    if(_attribctx_parser_append_attr(ctx, $1, &btrue, sizeof(CK_BBOOL) )!=rc_ok) {
117 			clerror(ctx,"Error during parsing, cannot assign boolean value.");
118 			YYERROR;
119 		    }
120 		}
121 	|	CKATTR_STR ASSIGN STRING
122                 {
123 		    if(_attribctx_parser_append_attr(ctx, $1, $3.val, $3.len)!=rc_ok) {
124 			clerror(ctx,"Error during parsing, cannot assign bytes value.");
125 			free($3.val); /* we must free() as the buffer was copied */
126 			YYERROR;
127 		    }
128 		    free($3.val); /* we must free() as the buffer was copied */
129 		}
130 	|	CKATTR_DATE ASSIGN TOK_DATE
131                 {
132 		    if(_attribctx_parser_append_attr(ctx, $1, $3.as_buffer, sizeof(CK_DATE))!=rc_ok) {
133 			clerror(ctx,"Error during parsing, cannot assign date value.");
134 			YYERROR;
135 		    }
136 		}
137 	|	CKATTR_DATE  ASSIGN STRING /* if the date comes as 0x... format (not preferred but accepted) */
138                 {
139 		    if(_attribctx_parser_append_attr(ctx, $1, $3.val, $3.len)!=rc_ok) {
140 			clerror(ctx,"Error during parsing, cannot assign date value.");
141 			free($3.val); /* we must free() as the buffer was copied */
142 			YYERROR;
143 		    }
144 		    free($3.val); /* we must free() as the buffer was copied */
145 		}
146 	|	CKATTR_KEY ASSIGN KEYTYPE
147                 {
148 		    if(_attribctx_parser_append_attr(ctx, $1, &$3, sizeof(CK_KEY_TYPE))!=rc_ok) {
149 			clerror(ctx,"Error during parsing, cannot assign key type value.");
150 			YYERROR;
151 		    }
152 		}
153 	|	CKATTR_CLASS ASSIGN OCLASS
154                 {
155 		    if(_attribctx_parser_append_attr(ctx, $1, &$3, sizeof(CK_OBJECT_CLASS))!=rc_ok) {
156 			clerror(ctx,"Error during parsing, cannot assign object class value.");
157 			YYERROR;
158 		    }
159 		}
160 		;
161 
162 template_expr:	CKATTR_TEMPLATE ASSIGN CURLY_OPEN
163 		{
164 		    if(ctx->level==1) {
165 			clerror(ctx, "***Error: nesting templates not allowed");
166 			YYERROR;
167 		    }
168                     ctx->level++; /*remind we are in a curly brace */
169 
170 		    ctx->current_idx = ctx->saved_idx + 1; /*increment current idx from ctx->saved_idx */
171 		    if(ctx->current_idx>=4) {
172 			clerror(ctx, "***Error: too many templates specified");
173 			YYERROR;
174                    }
175 		}
176 		statement CURLY_CLOSE
177 		{
178 
179 		    if(ctx->level==0) {
180 		        clerror(ctx, "***Error: no matching opening curly brace");
181 			YYERROR;
182                     }
183                     ctx->level--; /*out of curly brace now */
184 
185 		    ctx->saved_idx = ctx->current_idx; /* remember which index we used last */
186 		    ctx->current_idx = ctx->mainlist_idx; /* should be always 0 */
187 
188 		    if(_attribctx_parser_assign_list_to_template(ctx, $1)!=rc_ok) {
189 			clerror(ctx, "Error during parsing, cannot assign attribute list to a template attribute.");
190 			YYERROR;
191 		    }
192 		}
193 	;
194 
195 allowedmech_expr: CKATTR_ALLOWEDMECH ASSIGN CURLY_OPEN mechanisms CURLY_CLOSE
196 		{
197 		    if( _attribctx_parser_append_attr( ctx,
198 						       $1,
199 						       pkcs11_attribctx_get_allowed_mechanisms(ctx),
200 						       pkcs11_attribctx_get_allowed_mechanisms_len(ctx))
201 			!= rc_ok) {
202 			clerror(ctx,"Error during parsing, cannot assign object class value.");
203 			YYERROR;
204 		    }
205 		    /* pointer stolen, we must free it */
206 		    pkcs11_attribctx_forget_mechanisms(ctx);
207 		}
208 		;
209 
210 mechanisms:	mechanism
211 	|	mechanisms mechanism
212 	;
213 
214 mechanism:	CKMECH
215 		{
216 		    if( pkcs11_attribctx_add_mechanism(ctx, $1)!=rc_ok) {
217 			clerror(ctx, "Error during parsing, cannot assign mechanism to allowed mechanisms.");
218 			YYERROR;
219 		    }
220 		}
221 	;
222 %%
223