diff options
author | jsing <> | 2019-08-10 16:42:20 +0000 |
---|---|---|
committer | jsing <> | 2019-08-10 16:42:20 +0000 |
commit | 348e8055f6b4ea773466a117767c16e615a549ab (patch) | |
tree | fd2cdff41f524a9488d8863f2cd9058c06fe6058 /src/lib/libcrypto/cms/cms_pwri.c | |
parent | d2294fe6ec6b67e094cc8b699125f5d1027c17e3 (diff) | |
download | openbsd-348e8055f6b4ea773466a117767c16e615a549ab.tar.gz openbsd-348e8055f6b4ea773466a117767c16e615a549ab.tar.bz2 openbsd-348e8055f6b4ea773466a117767c16e615a549ab.zip |
First pass at style(9).
Whitespace only and no change according to diff -w.
Diffstat (limited to 'src/lib/libcrypto/cms/cms_pwri.c')
-rw-r--r-- | src/lib/libcrypto/cms/cms_pwri.c | 674 |
1 files changed, 337 insertions, 337 deletions
diff --git a/src/lib/libcrypto/cms/cms_pwri.c b/src/lib/libcrypto/cms/cms_pwri.c index a8030471e6..d7f5697ff0 100644 --- a/src/lib/libcrypto/cms/cms_pwri.c +++ b/src/lib/libcrypto/cms/cms_pwri.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: cms_pwri.c,v 1.15 2019/08/10 16:39:17 jsing Exp $ */ | 1 | /* $OpenBSD: cms_pwri.c,v 1.16 2019/08/10 16:42:20 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 3 | * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
4 | * project. | 4 | * project. |
@@ -64,152 +64,152 @@ | |||
64 | #include "asn1/asn1_locl.h" | 64 | #include "asn1/asn1_locl.h" |
65 | 65 | ||
66 | int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, | 66 | int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, |
67 | unsigned char *pass, ossl_ssize_t passlen) | 67 | unsigned char *pass, ossl_ssize_t passlen) |
68 | { | 68 | { |
69 | CMS_PasswordRecipientInfo *pwri; | 69 | CMS_PasswordRecipientInfo *pwri; |
70 | if (ri->type != CMS_RECIPINFO_PASS) { | 70 | if (ri->type != CMS_RECIPINFO_PASS) { |
71 | CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD, CMS_R_NOT_PWRI); | 71 | CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD, CMS_R_NOT_PWRI); |
72 | return 0; | 72 | return 0; |
73 | } | 73 | } |
74 | 74 | ||
75 | pwri = ri->d.pwri; | 75 | pwri = ri->d.pwri; |
76 | pwri->pass = pass; | 76 | pwri->pass = pass; |
77 | if (pass && passlen < 0) | 77 | if (pass && passlen < 0) |
78 | passlen = strlen((char *)pass); | 78 | passlen = strlen((char *)pass); |
79 | pwri->passlen = passlen; | 79 | pwri->passlen = passlen; |
80 | return 1; | 80 | return 1; |
81 | } | 81 | } |
82 | 82 | ||
83 | CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, | 83 | CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, |
84 | int iter, int wrap_nid, | 84 | int iter, int wrap_nid, |
85 | int pbe_nid, | 85 | int pbe_nid, |
86 | unsigned char *pass, | 86 | unsigned char *pass, |
87 | ossl_ssize_t passlen, | 87 | ossl_ssize_t passlen, |
88 | const EVP_CIPHER *kekciph) | 88 | const EVP_CIPHER *kekciph) |
89 | { | 89 | { |
90 | CMS_RecipientInfo *ri = NULL; | 90 | CMS_RecipientInfo *ri = NULL; |
91 | CMS_EnvelopedData *env; | 91 | CMS_EnvelopedData *env; |
92 | CMS_PasswordRecipientInfo *pwri; | 92 | CMS_PasswordRecipientInfo *pwri; |
93 | EVP_CIPHER_CTX *ctx = NULL; | 93 | EVP_CIPHER_CTX *ctx = NULL; |
94 | X509_ALGOR *encalg = NULL; | 94 | X509_ALGOR *encalg = NULL; |
95 | unsigned char iv[EVP_MAX_IV_LENGTH]; | 95 | unsigned char iv[EVP_MAX_IV_LENGTH]; |
96 | int ivlen; | 96 | int ivlen; |
97 | 97 | ||
98 | env = cms_get0_enveloped(cms); | 98 | env = cms_get0_enveloped(cms); |
99 | if (!env) | 99 | if (!env) |
100 | return NULL; | 100 | return NULL; |
101 | 101 | ||
102 | if (wrap_nid <= 0) | 102 | if (wrap_nid <= 0) |
103 | wrap_nid = NID_id_alg_PWRI_KEK; | 103 | wrap_nid = NID_id_alg_PWRI_KEK; |
104 | 104 | ||
105 | if (pbe_nid <= 0) | 105 | if (pbe_nid <= 0) |
106 | pbe_nid = NID_id_pbkdf2; | 106 | pbe_nid = NID_id_pbkdf2; |
107 | 107 | ||
108 | /* Get from enveloped data */ | 108 | /* Get from enveloped data */ |
109 | if (kekciph == NULL) | 109 | if (kekciph == NULL) |
110 | kekciph = env->encryptedContentInfo->cipher; | 110 | kekciph = env->encryptedContentInfo->cipher; |
111 | 111 | ||
112 | if (kekciph == NULL) { | 112 | if (kekciph == NULL) { |
113 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, CMS_R_NO_CIPHER); | 113 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, CMS_R_NO_CIPHER); |
114 | return NULL; | 114 | return NULL; |
115 | } | 115 | } |
116 | if (wrap_nid != NID_id_alg_PWRI_KEK) { | 116 | if (wrap_nid != NID_id_alg_PWRI_KEK) { |
117 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, | 117 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, |
118 | CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); | 118 | CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); |
119 | return NULL; | 119 | return NULL; |
120 | } | 120 | } |
121 | 121 | ||
122 | /* Setup algorithm identifier for cipher */ | 122 | /* Setup algorithm identifier for cipher */ |
123 | encalg = X509_ALGOR_new(); | 123 | encalg = X509_ALGOR_new(); |
124 | if (encalg == NULL) { | 124 | if (encalg == NULL) { |
125 | goto merr; | 125 | goto merr; |
126 | } | 126 | } |
127 | ctx = EVP_CIPHER_CTX_new(); | 127 | ctx = EVP_CIPHER_CTX_new(); |
128 | 128 | ||
129 | if (EVP_EncryptInit_ex(ctx, kekciph, NULL, NULL, NULL) <= 0) { | 129 | if (EVP_EncryptInit_ex(ctx, kekciph, NULL, NULL, NULL) <= 0) { |
130 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB); | 130 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB); |
131 | goto err; | 131 | goto err; |
132 | } | 132 | } |
133 | 133 | ||
134 | ivlen = EVP_CIPHER_CTX_iv_length(ctx); | 134 | ivlen = EVP_CIPHER_CTX_iv_length(ctx); |
135 | 135 | ||
136 | if (ivlen > 0) { | 136 | if (ivlen > 0) { |
137 | if (RAND_bytes(iv, ivlen) <= 0) | 137 | if (RAND_bytes(iv, ivlen) <= 0) |
138 | goto err; | 138 | goto err; |
139 | if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0) { | 139 | if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0) { |
140 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB); | 140 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB); |
141 | goto err; | 141 | goto err; |
142 | } | 142 | } |
143 | encalg->parameter = ASN1_TYPE_new(); | 143 | encalg->parameter = ASN1_TYPE_new(); |
144 | if (!encalg->parameter) { | 144 | if (!encalg->parameter) { |
145 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE); | 145 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE); |
146 | goto err; | 146 | goto err; |
147 | } | 147 | } |
148 | if (EVP_CIPHER_param_to_asn1(ctx, encalg->parameter) <= 0) { | 148 | if (EVP_CIPHER_param_to_asn1(ctx, encalg->parameter) <= 0) { |
149 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, | 149 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, |
150 | CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); | 150 | CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); |
151 | goto err; | 151 | goto err; |
152 | } | 152 | } |
153 | } | 153 | } |
154 | 154 | ||
155 | encalg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx)); | 155 | encalg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx)); |
156 | 156 | ||
157 | EVP_CIPHER_CTX_free(ctx); | 157 | EVP_CIPHER_CTX_free(ctx); |
158 | ctx = NULL; | 158 | ctx = NULL; |
159 | 159 | ||
160 | /* Initialize recipient info */ | 160 | /* Initialize recipient info */ |
161 | ri = M_ASN1_new_of(CMS_RecipientInfo); | 161 | ri = M_ASN1_new_of(CMS_RecipientInfo); |
162 | if (ri == NULL) | 162 | if (ri == NULL) |
163 | goto merr; | 163 | goto merr; |
164 | 164 | ||
165 | ri->d.pwri = M_ASN1_new_of(CMS_PasswordRecipientInfo); | 165 | ri->d.pwri = M_ASN1_new_of(CMS_PasswordRecipientInfo); |
166 | if (ri->d.pwri == NULL) | 166 | if (ri->d.pwri == NULL) |
167 | goto merr; | 167 | goto merr; |
168 | ri->type = CMS_RECIPINFO_PASS; | 168 | ri->type = CMS_RECIPINFO_PASS; |
169 | 169 | ||
170 | pwri = ri->d.pwri; | 170 | pwri = ri->d.pwri; |
171 | /* Since this is overwritten, free up empty structure already there */ | 171 | /* Since this is overwritten, free up empty structure already there */ |
172 | X509_ALGOR_free(pwri->keyEncryptionAlgorithm); | 172 | X509_ALGOR_free(pwri->keyEncryptionAlgorithm); |
173 | pwri->keyEncryptionAlgorithm = X509_ALGOR_new(); | 173 | pwri->keyEncryptionAlgorithm = X509_ALGOR_new(); |
174 | if (pwri->keyEncryptionAlgorithm == NULL) | 174 | if (pwri->keyEncryptionAlgorithm == NULL) |
175 | goto merr; | 175 | goto merr; |
176 | pwri->keyEncryptionAlgorithm->algorithm = OBJ_nid2obj(wrap_nid); | 176 | pwri->keyEncryptionAlgorithm->algorithm = OBJ_nid2obj(wrap_nid); |
177 | pwri->keyEncryptionAlgorithm->parameter = ASN1_TYPE_new(); | 177 | pwri->keyEncryptionAlgorithm->parameter = ASN1_TYPE_new(); |
178 | if (pwri->keyEncryptionAlgorithm->parameter == NULL) | 178 | if (pwri->keyEncryptionAlgorithm->parameter == NULL) |
179 | goto merr; | 179 | goto merr; |
180 | 180 | ||
181 | if (!ASN1_item_pack(encalg, ASN1_ITEM_rptr(X509_ALGOR), | 181 | if (!ASN1_item_pack(encalg, ASN1_ITEM_rptr(X509_ALGOR), |
182 | &pwri->keyEncryptionAlgorithm->parameter-> | 182 | &pwri->keyEncryptionAlgorithm->parameter-> |
183 | value.sequence)) | 183 | value.sequence)) |
184 | goto merr; | 184 | goto merr; |
185 | pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE; | 185 | pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE; |
186 | 186 | ||
187 | X509_ALGOR_free(encalg); | 187 | X509_ALGOR_free(encalg); |
188 | encalg = NULL; | 188 | encalg = NULL; |
189 | 189 | ||
190 | /* Setup PBE algorithm */ | 190 | /* Setup PBE algorithm */ |
191 | 191 | ||
192 | pwri->keyDerivationAlgorithm = PKCS5_pbkdf2_set(iter, NULL, 0, -1, -1); | 192 | pwri->keyDerivationAlgorithm = PKCS5_pbkdf2_set(iter, NULL, 0, -1, -1); |
193 | 193 | ||
194 | if (!pwri->keyDerivationAlgorithm) | 194 | if (!pwri->keyDerivationAlgorithm) |
195 | goto err; | 195 | goto err; |
196 | 196 | ||
197 | CMS_RecipientInfo_set0_password(ri, pass, passlen); | 197 | CMS_RecipientInfo_set0_password(ri, pass, passlen); |
198 | pwri->version = 0; | 198 | pwri->version = 0; |
199 | 199 | ||
200 | if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) | 200 | if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) |
201 | goto merr; | 201 | goto merr; |
202 | 202 | ||
203 | return ri; | 203 | return ri; |
204 | 204 | ||
205 | merr: | 205 | merr: |
206 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE); | 206 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE); |
207 | err: | 207 | err: |
208 | EVP_CIPHER_CTX_free(ctx); | 208 | EVP_CIPHER_CTX_free(ctx); |
209 | if (ri) | 209 | if (ri) |
210 | M_ASN1_free_of(ri, CMS_RecipientInfo); | 210 | M_ASN1_free_of(ri, CMS_RecipientInfo); |
211 | X509_ALGOR_free(encalg); | 211 | X509_ALGOR_free(encalg); |
212 | return NULL; | 212 | return NULL; |
213 | 213 | ||
214 | } | 214 | } |
215 | 215 | ||
@@ -219,221 +219,221 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, | |||
219 | */ | 219 | */ |
220 | 220 | ||
221 | static int kek_unwrap_key(unsigned char *out, size_t *outlen, | 221 | static int kek_unwrap_key(unsigned char *out, size_t *outlen, |
222 | const unsigned char *in, size_t inlen, | 222 | const unsigned char *in, size_t inlen, |
223 | EVP_CIPHER_CTX *ctx) | 223 | EVP_CIPHER_CTX *ctx) |
224 | { | 224 | { |
225 | size_t blocklen = EVP_CIPHER_CTX_block_size(ctx); | 225 | size_t blocklen = EVP_CIPHER_CTX_block_size(ctx); |
226 | unsigned char *tmp; | 226 | unsigned char *tmp; |
227 | int outl, rv = 0; | 227 | int outl, rv = 0; |
228 | if (inlen < 2 * blocklen) { | 228 | if (inlen < 2 * blocklen) { |
229 | /* too small */ | 229 | /* too small */ |
230 | return 0; | 230 | return 0; |
231 | } | 231 | } |
232 | if (inlen % blocklen) { | 232 | if (inlen % blocklen) { |
233 | /* Invalid size */ | 233 | /* Invalid size */ |
234 | return 0; | 234 | return 0; |
235 | } | 235 | } |
236 | if ((tmp = OPENSSL_malloc(inlen)) == NULL) { | 236 | if ((tmp = OPENSSL_malloc(inlen)) == NULL) { |
237 | CMSerr(CMS_F_KEK_UNWRAP_KEY, ERR_R_MALLOC_FAILURE); | 237 | CMSerr(CMS_F_KEK_UNWRAP_KEY, ERR_R_MALLOC_FAILURE); |
238 | return 0; | 238 | return 0; |
239 | } | 239 | } |
240 | /* setup IV by decrypting last two blocks */ | 240 | /* setup IV by decrypting last two blocks */ |
241 | if (!EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl, | 241 | if (!EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl, |
242 | in + inlen - 2 * blocklen, blocklen * 2) | 242 | in + inlen - 2 * blocklen, blocklen * 2) |
243 | /* | 243 | /* |
244 | * Do a decrypt of last decrypted block to set IV to correct value | 244 | * Do a decrypt of last decrypted block to set IV to correct value |
245 | * output it to start of buffer so we don't corrupt decrypted block | 245 | * output it to start of buffer so we don't corrupt decrypted block |
246 | * this works because buffer is at least two block lengths long. | 246 | * this works because buffer is at least two block lengths long. |
247 | */ | 247 | */ |
248 | || !EVP_DecryptUpdate(ctx, tmp, &outl, | 248 | || !EVP_DecryptUpdate(ctx, tmp, &outl, |
249 | tmp + inlen - blocklen, blocklen) | 249 | tmp + inlen - blocklen, blocklen) |
250 | /* Can now decrypt first n - 1 blocks */ | 250 | /* Can now decrypt first n - 1 blocks */ |
251 | || !EVP_DecryptUpdate(ctx, tmp, &outl, in, inlen - blocklen) | 251 | || !EVP_DecryptUpdate(ctx, tmp, &outl, in, inlen - blocklen) |
252 | 252 | ||
253 | /* Reset IV to original value */ | 253 | /* Reset IV to original value */ |
254 | || !EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL) | 254 | || !EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL) |
255 | /* Decrypt again */ | 255 | /* Decrypt again */ |
256 | || !EVP_DecryptUpdate(ctx, tmp, &outl, tmp, inlen)) | 256 | || !EVP_DecryptUpdate(ctx, tmp, &outl, tmp, inlen)) |
257 | goto err; | 257 | goto err; |
258 | /* Check check bytes */ | 258 | /* Check check bytes */ |
259 | if (((tmp[1] ^ tmp[4]) & (tmp[2] ^ tmp[5]) & (tmp[3] ^ tmp[6])) != 0xff) { | 259 | if (((tmp[1] ^ tmp[4]) & (tmp[2] ^ tmp[5]) & (tmp[3] ^ tmp[6])) != 0xff) { |
260 | /* Check byte failure */ | 260 | /* Check byte failure */ |
261 | goto err; | 261 | goto err; |
262 | } | 262 | } |
263 | if (inlen < (size_t)(tmp[0] - 4)) { | 263 | if (inlen < (size_t)(tmp[0] - 4)) { |
264 | /* Invalid length value */ | 264 | /* Invalid length value */ |
265 | goto err; | 265 | goto err; |
266 | } | 266 | } |
267 | *outlen = (size_t)tmp[0]; | 267 | *outlen = (size_t)tmp[0]; |
268 | memcpy(out, tmp + 4, *outlen); | 268 | memcpy(out, tmp + 4, *outlen); |
269 | rv = 1; | 269 | rv = 1; |
270 | err: | 270 | err: |
271 | OPENSSL_clear_free(tmp, inlen); | 271 | OPENSSL_clear_free(tmp, inlen); |
272 | return rv; | 272 | return rv; |
273 | 273 | ||
274 | } | 274 | } |
275 | 275 | ||
276 | static int kek_wrap_key(unsigned char *out, size_t *outlen, | 276 | static int kek_wrap_key(unsigned char *out, size_t *outlen, |
277 | const unsigned char *in, size_t inlen, | 277 | const unsigned char *in, size_t inlen, |
278 | EVP_CIPHER_CTX *ctx) | 278 | EVP_CIPHER_CTX *ctx) |
279 | { | 279 | { |
280 | size_t blocklen = EVP_CIPHER_CTX_block_size(ctx); | 280 | size_t blocklen = EVP_CIPHER_CTX_block_size(ctx); |
281 | size_t olen; | 281 | size_t olen; |
282 | int dummy; | 282 | int dummy; |
283 | /* | 283 | /* |
284 | * First decide length of output buffer: need header and round up to | 284 | * First decide length of output buffer: need header and round up to |
285 | * multiple of block length. | 285 | * multiple of block length. |
286 | */ | 286 | */ |
287 | olen = (inlen + 4 + blocklen - 1) / blocklen; | 287 | olen = (inlen + 4 + blocklen - 1) / blocklen; |
288 | olen *= blocklen; | 288 | olen *= blocklen; |
289 | if (olen < 2 * blocklen) { | 289 | if (olen < 2 * blocklen) { |
290 | /* Key too small */ | 290 | /* Key too small */ |
291 | return 0; | 291 | return 0; |
292 | } | 292 | } |
293 | if (inlen > 0xFF) { | 293 | if (inlen > 0xFF) { |
294 | /* Key too large */ | 294 | /* Key too large */ |
295 | return 0; | 295 | return 0; |
296 | } | 296 | } |
297 | if (out) { | 297 | if (out) { |
298 | /* Set header */ | 298 | /* Set header */ |
299 | out[0] = (unsigned char)inlen; | 299 | out[0] = (unsigned char)inlen; |
300 | out[1] = in[0] ^ 0xFF; | 300 | out[1] = in[0] ^ 0xFF; |
301 | out[2] = in[1] ^ 0xFF; | 301 | out[2] = in[1] ^ 0xFF; |
302 | out[3] = in[2] ^ 0xFF; | 302 | out[3] = in[2] ^ 0xFF; |
303 | memcpy(out + 4, in, inlen); | 303 | memcpy(out + 4, in, inlen); |
304 | /* Add random padding to end */ | 304 | /* Add random padding to end */ |
305 | if (olen > inlen + 4 | 305 | if (olen > inlen + 4 |
306 | && RAND_bytes(out + 4 + inlen, olen - 4 - inlen) <= 0) | 306 | && RAND_bytes(out + 4 + inlen, olen - 4 - inlen) <= 0) |
307 | return 0; | 307 | return 0; |
308 | /* Encrypt twice */ | 308 | /* Encrypt twice */ |
309 | if (!EVP_EncryptUpdate(ctx, out, &dummy, out, olen) | 309 | if (!EVP_EncryptUpdate(ctx, out, &dummy, out, olen) |
310 | || !EVP_EncryptUpdate(ctx, out, &dummy, out, olen)) | 310 | || !EVP_EncryptUpdate(ctx, out, &dummy, out, olen)) |
311 | return 0; | 311 | return 0; |
312 | } | 312 | } |
313 | 313 | ||
314 | *outlen = olen; | 314 | *outlen = olen; |
315 | 315 | ||
316 | return 1; | 316 | return 1; |
317 | } | 317 | } |
318 | 318 | ||
319 | /* Encrypt/Decrypt content key in PWRI recipient info */ | 319 | /* Encrypt/Decrypt content key in PWRI recipient info */ |
320 | 320 | ||
321 | int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, | 321 | int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, |
322 | int en_de) | 322 | int en_de) |
323 | { | 323 | { |
324 | CMS_EncryptedContentInfo *ec; | 324 | CMS_EncryptedContentInfo *ec; |
325 | CMS_PasswordRecipientInfo *pwri; | 325 | CMS_PasswordRecipientInfo *pwri; |
326 | int r = 0; | 326 | int r = 0; |
327 | X509_ALGOR *algtmp, *kekalg = NULL; | 327 | X509_ALGOR *algtmp, *kekalg = NULL; |
328 | EVP_CIPHER_CTX *kekctx = NULL; | 328 | EVP_CIPHER_CTX *kekctx = NULL; |
329 | const EVP_CIPHER *kekcipher; | 329 | const EVP_CIPHER *kekcipher; |
330 | unsigned char *key = NULL; | 330 | unsigned char *key = NULL; |
331 | size_t keylen; | 331 | size_t keylen; |
332 | 332 | ||
333 | ec = cms->d.envelopedData->encryptedContentInfo; | 333 | ec = cms->d.envelopedData->encryptedContentInfo; |
334 | 334 | ||
335 | pwri = ri->d.pwri; | 335 | pwri = ri->d.pwri; |
336 | 336 | ||
337 | if (!pwri->pass) { | 337 | if (!pwri->pass) { |
338 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_NO_PASSWORD); | 338 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_NO_PASSWORD); |
339 | return 0; | 339 | return 0; |
340 | } | 340 | } |
341 | algtmp = pwri->keyEncryptionAlgorithm; | 341 | algtmp = pwri->keyEncryptionAlgorithm; |
342 | 342 | ||
343 | if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK) { | 343 | if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK) { |
344 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, | 344 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, |
345 | CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); | 345 | CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); |
346 | return 0; | 346 | return 0; |
347 | } | 347 | } |
348 | 348 | ||
349 | kekalg = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(X509_ALGOR), | 349 | kekalg = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(X509_ALGOR), |
350 | algtmp->parameter); | 350 | algtmp->parameter); |
351 | 351 | ||
352 | if (kekalg == NULL) { | 352 | if (kekalg == NULL) { |
353 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, | 353 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, |
354 | CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER); | 354 | CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER); |
355 | return 0; | 355 | return 0; |
356 | } | 356 | } |
357 | 357 | ||
358 | kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); | 358 | kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); |
359 | 359 | ||
360 | if (!kekcipher) { | 360 | if (!kekcipher) { |
361 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNKNOWN_CIPHER); | 361 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNKNOWN_CIPHER); |
362 | return 0; | 362 | return 0; |
363 | } | 363 | } |
364 | 364 | ||
365 | kekctx = EVP_CIPHER_CTX_new(); | 365 | kekctx = EVP_CIPHER_CTX_new(); |
366 | if (kekctx == NULL) { | 366 | if (kekctx == NULL) { |
367 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE); | 367 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE); |
368 | return 0; | 368 | return 0; |
369 | } | 369 | } |
370 | /* Fixup cipher based on AlgorithmIdentifier to set IV etc */ | 370 | /* Fixup cipher based on AlgorithmIdentifier to set IV etc */ |
371 | if (!EVP_CipherInit_ex(kekctx, kekcipher, NULL, NULL, NULL, en_de)) | 371 | if (!EVP_CipherInit_ex(kekctx, kekcipher, NULL, NULL, NULL, en_de)) |
372 | goto err; | 372 | goto err; |
373 | EVP_CIPHER_CTX_set_padding(kekctx, 0); | 373 | EVP_CIPHER_CTX_set_padding(kekctx, 0); |
374 | if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) { | 374 | if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) { |
375 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, | 375 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, |
376 | CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); | 376 | CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); |
377 | goto err; | 377 | goto err; |
378 | } | 378 | } |
379 | 379 | ||
380 | algtmp = pwri->keyDerivationAlgorithm; | 380 | algtmp = pwri->keyDerivationAlgorithm; |
381 | 381 | ||
382 | /* Finish password based key derivation to setup key in "ctx" */ | 382 | /* Finish password based key derivation to setup key in "ctx" */ |
383 | 383 | ||
384 | if (EVP_PBE_CipherInit(algtmp->algorithm, | 384 | if (EVP_PBE_CipherInit(algtmp->algorithm, |
385 | (char *)pwri->pass, pwri->passlen, | 385 | (char *)pwri->pass, pwri->passlen, |
386 | algtmp->parameter, kekctx, en_de) < 0) { | 386 | algtmp->parameter, kekctx, en_de) < 0) { |
387 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_EVP_LIB); | 387 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_EVP_LIB); |
388 | goto err; | 388 | goto err; |
389 | } | 389 | } |
390 | 390 | ||
391 | /* Finally wrap/unwrap the key */ | 391 | /* Finally wrap/unwrap the key */ |
392 | 392 | ||
393 | if (en_de) { | 393 | if (en_de) { |
394 | 394 | ||
395 | if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, kekctx)) | 395 | if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, kekctx)) |
396 | goto err; | 396 | goto err; |
397 | 397 | ||
398 | key = OPENSSL_malloc(keylen); | 398 | key = OPENSSL_malloc(keylen); |
399 | 399 | ||
400 | if (key == NULL) | 400 | if (key == NULL) |
401 | goto err; | 401 | goto err; |
402 | 402 | ||
403 | if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, kekctx)) | 403 | if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, kekctx)) |
404 | goto err; | 404 | goto err; |
405 | pwri->encryptedKey->data = key; | 405 | pwri->encryptedKey->data = key; |
406 | pwri->encryptedKey->length = keylen; | 406 | pwri->encryptedKey->length = keylen; |
407 | } else { | 407 | } else { |
408 | key = OPENSSL_malloc(pwri->encryptedKey->length); | 408 | key = OPENSSL_malloc(pwri->encryptedKey->length); |
409 | 409 | ||
410 | if (key == NULL) { | 410 | if (key == NULL) { |
411 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE); | 411 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE); |
412 | goto err; | 412 | goto err; |
413 | } | 413 | } |
414 | if (!kek_unwrap_key(key, &keylen, | 414 | if (!kek_unwrap_key(key, &keylen, |
415 | pwri->encryptedKey->data, | 415 | pwri->encryptedKey->data, |
416 | pwri->encryptedKey->length, kekctx)) { | 416 | pwri->encryptedKey->length, kekctx)) { |
417 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNWRAP_FAILURE); | 417 | CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNWRAP_FAILURE); |
418 | goto err; | 418 | goto err; |
419 | } | 419 | } |
420 | 420 | ||
421 | OPENSSL_clear_free(ec->key, ec->keylen); | 421 | OPENSSL_clear_free(ec->key, ec->keylen); |
422 | ec->key = key; | 422 | ec->key = key; |
423 | ec->keylen = keylen; | 423 | ec->keylen = keylen; |
424 | 424 | ||
425 | } | 425 | } |
426 | 426 | ||
427 | r = 1; | 427 | r = 1; |
428 | 428 | ||
429 | err: | 429 | err: |
430 | 430 | ||
431 | EVP_CIPHER_CTX_free(kekctx); | 431 | EVP_CIPHER_CTX_free(kekctx); |
432 | 432 | ||
433 | if (!r) | 433 | if (!r) |
434 | OPENSSL_free(key); | 434 | OPENSSL_free(key); |
435 | X509_ALGOR_free(kekalg); | 435 | X509_ALGOR_free(kekalg); |
436 | 436 | ||
437 | return r; | 437 | return r; |
438 | 438 | ||
439 | } | 439 | } |