1 /* -*- mode: c; c-file-style:"stroustrup"; -*- */
2
3 /*
4 * Copyright (c) 2018 Mastercard
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #include <config.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <assert.h>
24 #include <search.h>
25
26 #include <openssl/bio.h>
27 #include <openssl/pem.h>
28 #include <openssl/x509.h>
29
30 #include "pkcs11lib.h"
31 #include "wrappedkey_lexer.h"
32 #include "wrappedkey_parser.h"
33
34
35 /* wrappedKeyContext will hold information about wrapping/unwrapping keys
36
37 several wrapping methods are supported:
38 - the regular wrapping methods ( PKCS#1, OAEP, CBC_PAD, AES_KEY_WRAP, AES_KEY_WRAP_PAD )
39 - envelope wrapping, where a private key (RSA) wraps a symmetric key, that in turn wraps any kind of key
40
41 to support both models, the structure contains a small array where actual wrapped key info is maintained.
42
43 ...
44 struct {
45 CK_BYTE_PTR wrapped_key_buffer;
46 CK_ULONG wrapped_key_len;
47 enum wrappingmethod wrapping_meth;
48 } key[2];
49 ...
50
51 the first element is always for the outer key, which is used only for envelope wrapping.
52 the second element is either used as the inner key in envelope mode, or as the lone key for other wrapping algorithms.
53
54 */
55
56
pkcs11_new_wrappedkeycontext(pkcs11Context * p11Context)57 wrappedKeyCtx *pkcs11_new_wrappedkeycontext(pkcs11Context *p11Context)
58 {
59 wrappedKeyCtx *ctx = NULL;
60
61 if(p11Context) {
62 ctx = calloc(1, sizeof (wrappedKeyCtx));
63
64 if(ctx==NULL) {
65 fprintf(stderr, "Error: not enough memory when allocating memory for wrappedKeyCtx\n");
66 goto error;
67 }
68
69 ctx->p11Context = p11Context;
70
71 ctx->oaep_params = calloc( 1, sizeof(CK_RSA_PKCS_OAEP_PARAMS) );
72 if(ctx->oaep_params == NULL) {
73 fprintf(stderr, "Error: not enough memory when allocating memory for CK_RSA_PKCS_OAEP_PARAMS of wrappedKeyCtx\n");
74 goto error;
75 }
76
77 ctx->is_envelope = CK_FALSE;
78
79 ctx->wrpkattribs = pkcs11_new_attribcontext();
80 if(ctx->wrpkattribs == NULL) {
81 fprintf(stderr, "Error: not enough memory when allocating memory for wrpkattribs member\n");
82 goto error;
83 }
84
85 ctx->pubkattribs = pkcs11_new_attribcontext();
86 if(ctx->pubkattribs == NULL) {
87 fprintf(stderr, "Error: not enough memory when allocating memory for pubkattribs member\n");
88 goto error;
89 }
90 }
91
92 return ctx;
93
94 error:
95 if(ctx) {
96 if(ctx->wrpkattribs) pkcs11_free_attribcontext(ctx->wrpkattribs);
97 if(ctx->pubkattribs) pkcs11_free_attribcontext(ctx->pubkattribs);
98 pkcs11_free_wrappedkeycontext(ctx);
99 }
100 return NULL;
101 }
102
pkcs11_wctx_free_mechanisms(wrappedKeyCtx * wctx)103 inline void pkcs11_wctx_free_mechanisms(wrappedKeyCtx *wctx)
104 {
105 if(wctx && wctx->allowedmechs) {
106 free(wctx->allowedmechs);
107 wctx->allowedmechs = NULL;
108 wctx->allowedmechs_len = 0;
109 }
110 }
111
112 /* to use only for transfer of ownership */
pkcs11_wctx_forget_mechanisms(wrappedKeyCtx * wctx)113 inline void pkcs11_wctx_forget_mechanisms(wrappedKeyCtx *wctx)
114 {
115 if(wctx && wctx->allowedmechs) {
116 wctx->allowedmechs = NULL;
117 wctx->allowedmechs_len = 0;
118 }
119 }
120
pkcs11_wctx_get_allowed_mechanisms(wrappedKeyCtx * ctx)121 inline CK_MECHANISM_TYPE_PTR pkcs11_wctx_get_allowed_mechanisms(wrappedKeyCtx *ctx)
122 {
123 return ctx ? ctx->allowedmechs : NULL;
124 }
125
pkcs11_wctx_get_allowed_mechanisms_len(wrappedKeyCtx * ctx)126 inline size_t pkcs11_wctx_get_allowed_mechanisms_len(wrappedKeyCtx *ctx)
127 {
128 return ctx ? ctx->allowedmechs_len : 0;
129 }
130
131
pkcs11_free_wrappedkeycontext(wrappedKeyCtx * wctx)132 void pkcs11_free_wrappedkeycontext(wrappedKeyCtx *wctx)
133 {
134
135 if( wctx ) {
136
137 /* free up wrappingkeylabel */
138 if(wctx->wrappingkeylabel) {
139 free(wctx->wrappingkeylabel);
140 wctx->wrappingkeylabel= NULL ;
141 }
142
143 /* free up wrappedkeylabel */
144 if(wctx->wrappedkeylabel) {
145 free(wctx->wrappedkeylabel);
146 wctx->wrappedkeylabel = NULL ;
147 }
148
149 /* free up filename */
150 if(wctx->filename) {
151 free(wctx->filename);
152 wctx->filename = NULL;
153 }
154
155 /* free up allowed mechanisms array */
156 pkcs11_wctx_free_mechanisms(wctx);
157
158 /* free up buffers */
159 int i;
160 for(i=0; i<2; ++i) {
161 if(wctx->key[i].wrapped_key_buffer) {
162 free(wctx->key[i].wrapped_key_buffer);
163 wctx->key[i].wrapped_key_buffer = NULL;
164 wctx->key[i].wrapped_key_len = 0;
165 }
166 }
167
168 /* free up OAEP structure */
169 if(wctx->oaep_params) {
170 if(wctx->oaep_params->pSourceData) {
171 free(wctx->oaep_params->pSourceData);
172 wctx->oaep_params->pSourceData=NULL;
173 wctx->oaep_params->ulSourceDataLen=0L;
174 }
175 free(wctx->oaep_params);
176 wctx->oaep_params = NULL;
177 }
178
179 /* free up iv member */
180 if(wctx->aes_params.iv) {
181 free(wctx->aes_params.iv);
182 wctx->aes_params.iv = NULL;
183 wctx->aes_params.iv_len = 0L;
184 }
185
186 /* free up pubk_pem_buffer */
187 if(wctx->pubk_buffer) {
188 free(wctx->pubk_buffer);
189 wctx->pubk_buffer = NULL;
190 wctx->pubk_len=0;
191 }
192
193 /* free up wrappedkeyattribs */
194 if(wctx->wrpkattribs) {
195 pkcs11_free_attribcontext(wctx->wrpkattribs);
196 wctx->wrpkattribs = NULL;
197 }
198
199 /* free up pubkeyattribs */
200 if(wctx->pubkattribs) {
201 pkcs11_free_attribcontext(wctx->pubkattribs);
202 wctx->pubkattribs = NULL;
203 }
204
205 free(wctx); /* eventually free up context mem */
206 }
207 }
208