1 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
2 | * project 1999. |
3 | */ |
4 | /* ==================================================================== |
5 | * Copyright (c) 1999 The OpenSSL Project. All rights reserved. |
6 | * |
7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions |
9 | * are met: |
10 | * |
11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. |
13 | * |
14 | * 2. Redistributions in binary form must reproduce the above copyright |
15 | * notice, this list of conditions and the following disclaimer in |
16 | * the documentation and/or other materials provided with the |
17 | * distribution. |
18 | * |
19 | * 3. All advertising materials mentioning features or use of this |
20 | * software must display the following acknowledgment: |
21 | * "This product includes software developed by the OpenSSL Project |
22 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" |
23 | * |
24 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
25 | * endorse or promote products derived from this software without |
26 | * prior written permission. For written permission, please contact |
27 | * licensing@OpenSSL.org. |
28 | * |
29 | * 5. Products derived from this software may not be called "OpenSSL" |
30 | * nor may "OpenSSL" appear in their names without prior written |
31 | * permission of the OpenSSL Project. |
32 | * |
33 | * 6. Redistributions of any form whatsoever must retain the following |
34 | * acknowledgment: |
35 | * "This product includes software developed by the OpenSSL Project |
36 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" |
37 | * |
38 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
39 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
40 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
41 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
42 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
43 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
44 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
45 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
46 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
47 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
48 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
49 | * OF THE POSSIBILITY OF SUCH DAMAGE. |
50 | * ==================================================================== |
51 | * |
52 | * This product includes cryptographic software written by Eric Young |
53 | * (eay@cryptsoft.com). This product includes software written by Tim |
54 | * Hudson (tjh@cryptsoft.com). */ |
55 | |
56 | #include <openssl/pkcs8.h> |
57 | |
58 | #include <assert.h> |
59 | #include <limits.h> |
60 | #include <string.h> |
61 | |
62 | #include <openssl/bytestring.h> |
63 | #include <openssl/cipher.h> |
64 | #include <openssl/digest.h> |
65 | #include <openssl/err.h> |
66 | #include <openssl/mem.h> |
67 | #include <openssl/nid.h> |
68 | #include <openssl/rand.h> |
69 | |
70 | #include "internal.h" |
71 | #include "../bytestring/internal.h" |
72 | #include "../internal.h" |
73 | |
74 | |
75 | static int pkcs12_encode_password(const char *in, size_t in_len, uint8_t **out, |
76 | size_t *out_len) { |
77 | CBB cbb; |
78 | if (!CBB_init(&cbb, in_len * 2)) { |
79 | OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); |
80 | return 0; |
81 | } |
82 | |
83 | // Convert the password to BMPString, or UCS-2. See |
84 | // https://tools.ietf.org/html/rfc7292#appendix-B.1. |
85 | CBS cbs; |
86 | CBS_init(&cbs, (const uint8_t *)in, in_len); |
87 | while (CBS_len(&cbs) != 0) { |
88 | uint32_t c; |
89 | if (!cbs_get_utf8(&cbs, &c) || |
90 | !cbb_add_ucs2_be(&cbb, c)) { |
91 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_INVALID_CHARACTERS); |
92 | goto err; |
93 | } |
94 | } |
95 | |
96 | // Terminate the result with a UCS-2 NUL. |
97 | if (!cbb_add_ucs2_be(&cbb, 0) || |
98 | !CBB_finish(&cbb, out, out_len)) { |
99 | goto err; |
100 | } |
101 | |
102 | return 1; |
103 | |
104 | err: |
105 | CBB_cleanup(&cbb); |
106 | return 0; |
107 | } |
108 | |
109 | int pkcs12_key_gen(const char *pass, size_t pass_len, const uint8_t *salt, |
110 | size_t salt_len, uint8_t id, unsigned iterations, |
111 | size_t out_len, uint8_t *out, const EVP_MD *md) { |
112 | // See https://tools.ietf.org/html/rfc7292#appendix-B. Quoted parts of the |
113 | // specification have errata applied and other typos fixed. |
114 | |
115 | if (iterations < 1) { |
116 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_ITERATION_COUNT); |
117 | return 0; |
118 | } |
119 | |
120 | int ret = 0; |
121 | EVP_MD_CTX ctx; |
122 | EVP_MD_CTX_init(&ctx); |
123 | uint8_t *pass_raw = NULL, *I = NULL; |
124 | size_t pass_raw_len = 0, I_len = 0; |
125 | // If |pass| is NULL, we use the empty string rather than {0, 0} as the raw |
126 | // password. |
127 | if (pass != NULL && |
128 | !pkcs12_encode_password(pass, pass_len, &pass_raw, &pass_raw_len)) { |
129 | goto err; |
130 | } |
131 | |
132 | // In the spec, |block_size| is called "v", but measured in bits. |
133 | size_t block_size = EVP_MD_block_size(md); |
134 | |
135 | // 1. Construct a string, D (the "diversifier"), by concatenating v/8 copies |
136 | // of ID. |
137 | uint8_t D[EVP_MAX_MD_BLOCK_SIZE]; |
138 | OPENSSL_memset(D, id, block_size); |
139 | |
140 | // 2. Concatenate copies of the salt together to create a string S of length |
141 | // v(ceiling(s/v)) bits (the final copy of the salt may be truncated to |
142 | // create S). Note that if the salt is the empty string, then so is S. |
143 | // |
144 | // 3. Concatenate copies of the password together to create a string P of |
145 | // length v(ceiling(p/v)) bits (the final copy of the password may be |
146 | // truncated to create P). Note that if the password is the empty string, |
147 | // then so is P. |
148 | // |
149 | // 4. Set I=S||P to be the concatenation of S and P. |
150 | if (salt_len + block_size - 1 < salt_len || |
151 | pass_raw_len + block_size - 1 < pass_raw_len) { |
152 | OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW); |
153 | goto err; |
154 | } |
155 | size_t S_len = block_size * ((salt_len + block_size - 1) / block_size); |
156 | size_t P_len = block_size * ((pass_raw_len + block_size - 1) / block_size); |
157 | I_len = S_len + P_len; |
158 | if (I_len < S_len) { |
159 | OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW); |
160 | goto err; |
161 | } |
162 | |
163 | I = OPENSSL_malloc(I_len); |
164 | if (I_len != 0 && I == NULL) { |
165 | OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); |
166 | goto err; |
167 | } |
168 | |
169 | for (size_t i = 0; i < S_len; i++) { |
170 | I[i] = salt[i % salt_len]; |
171 | } |
172 | for (size_t i = 0; i < P_len; i++) { |
173 | I[i + S_len] = pass_raw[i % pass_raw_len]; |
174 | } |
175 | |
176 | while (out_len != 0) { |
177 | // A. Set A_i=H^r(D||I). (i.e., the r-th hash of D||I, |
178 | // H(H(H(... H(D||I)))) |
179 | uint8_t A[EVP_MAX_MD_SIZE]; |
180 | unsigned A_len; |
181 | if (!EVP_DigestInit_ex(&ctx, md, NULL) || |
182 | !EVP_DigestUpdate(&ctx, D, block_size) || |
183 | !EVP_DigestUpdate(&ctx, I, I_len) || |
184 | !EVP_DigestFinal_ex(&ctx, A, &A_len)) { |
185 | goto err; |
186 | } |
187 | for (unsigned iter = 1; iter < iterations; iter++) { |
188 | if (!EVP_DigestInit_ex(&ctx, md, NULL) || |
189 | !EVP_DigestUpdate(&ctx, A, A_len) || |
190 | !EVP_DigestFinal_ex(&ctx, A, &A_len)) { |
191 | goto err; |
192 | } |
193 | } |
194 | |
195 | size_t todo = out_len < A_len ? out_len : A_len; |
196 | OPENSSL_memcpy(out, A, todo); |
197 | out += todo; |
198 | out_len -= todo; |
199 | if (out_len == 0) { |
200 | break; |
201 | } |
202 | |
203 | // B. Concatenate copies of A_i to create a string B of length v bits (the |
204 | // final copy of A_i may be truncated to create B). |
205 | uint8_t B[EVP_MAX_MD_BLOCK_SIZE]; |
206 | for (size_t i = 0; i < block_size; i++) { |
207 | B[i] = A[i % A_len]; |
208 | } |
209 | |
210 | // C. Treating I as a concatenation I_0, I_1, ..., I_(k-1) of v-bit blocks, |
211 | // where k=ceiling(s/v)+ceiling(p/v), modify I by setting I_j=(I_j+B+1) mod |
212 | // 2^v for each j. |
213 | assert(I_len % block_size == 0); |
214 | for (size_t i = 0; i < I_len; i += block_size) { |
215 | unsigned carry = 1; |
216 | for (size_t j = block_size - 1; j < block_size; j--) { |
217 | carry += I[i + j] + B[j]; |
218 | I[i + j] = (uint8_t)carry; |
219 | carry >>= 8; |
220 | } |
221 | } |
222 | } |
223 | |
224 | ret = 1; |
225 | |
226 | err: |
227 | OPENSSL_free(I); |
228 | OPENSSL_free(pass_raw); |
229 | EVP_MD_CTX_cleanup(&ctx); |
230 | return ret; |
231 | } |
232 | |
233 | static int pkcs12_pbe_cipher_init(const struct pbe_suite *suite, |
234 | EVP_CIPHER_CTX *ctx, unsigned iterations, |
235 | const char *pass, size_t pass_len, |
236 | const uint8_t *salt, size_t salt_len, |
237 | int is_encrypt) { |
238 | const EVP_CIPHER *cipher = suite->cipher_func(); |
239 | const EVP_MD *md = suite->md_func(); |
240 | |
241 | uint8_t key[EVP_MAX_KEY_LENGTH]; |
242 | uint8_t iv[EVP_MAX_IV_LENGTH]; |
243 | if (!pkcs12_key_gen(pass, pass_len, salt, salt_len, PKCS12_KEY_ID, iterations, |
244 | EVP_CIPHER_key_length(cipher), key, md) || |
245 | !pkcs12_key_gen(pass, pass_len, salt, salt_len, PKCS12_IV_ID, iterations, |
246 | EVP_CIPHER_iv_length(cipher), iv, md)) { |
247 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_KEY_GEN_ERROR); |
248 | return 0; |
249 | } |
250 | |
251 | int ret = EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, is_encrypt); |
252 | OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); |
253 | OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH); |
254 | return ret; |
255 | } |
256 | |
257 | static int pkcs12_pbe_decrypt_init(const struct pbe_suite *suite, |
258 | EVP_CIPHER_CTX *ctx, const char *pass, |
259 | size_t pass_len, CBS *param) { |
260 | CBS pbe_param, salt; |
261 | uint64_t iterations; |
262 | if (!CBS_get_asn1(param, &pbe_param, CBS_ASN1_SEQUENCE) || |
263 | !CBS_get_asn1(&pbe_param, &salt, CBS_ASN1_OCTETSTRING) || |
264 | !CBS_get_asn1_uint64(&pbe_param, &iterations) || |
265 | CBS_len(&pbe_param) != 0 || |
266 | CBS_len(param) != 0) { |
267 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); |
268 | return 0; |
269 | } |
270 | |
271 | if (!pkcs12_iterations_acceptable(iterations)) { |
272 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_ITERATION_COUNT); |
273 | return 0; |
274 | } |
275 | |
276 | return pkcs12_pbe_cipher_init(suite, ctx, (unsigned)iterations, pass, |
277 | pass_len, CBS_data(&salt), CBS_len(&salt), |
278 | 0 /* decrypt */); |
279 | } |
280 | |
281 | static const struct pbe_suite kBuiltinPBE[] = { |
282 | { |
283 | NID_pbe_WithSHA1And40BitRC2_CBC, |
284 | // 1.2.840.113549.1.12.1.6 |
285 | {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x06}, |
286 | 10, |
287 | EVP_rc2_40_cbc, |
288 | EVP_sha1, |
289 | pkcs12_pbe_decrypt_init, |
290 | }, |
291 | { |
292 | NID_pbe_WithSHA1And128BitRC4, |
293 | // 1.2.840.113549.1.12.1.1 |
294 | {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x01}, |
295 | 10, |
296 | EVP_rc4, |
297 | EVP_sha1, |
298 | pkcs12_pbe_decrypt_init, |
299 | }, |
300 | { |
301 | NID_pbe_WithSHA1And3_Key_TripleDES_CBC, |
302 | // 1.2.840.113549.1.12.1.3 |
303 | {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03}, |
304 | 10, |
305 | EVP_des_ede3_cbc, |
306 | EVP_sha1, |
307 | pkcs12_pbe_decrypt_init, |
308 | }, |
309 | { |
310 | NID_pbes2, |
311 | // 1.2.840.113549.1.5.13 |
312 | {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0d}, |
313 | 9, |
314 | NULL, |
315 | NULL, |
316 | PKCS5_pbe2_decrypt_init, |
317 | }, |
318 | }; |
319 | |
320 | static const struct pbe_suite *get_pkcs12_pbe_suite(int pbe_nid) { |
321 | for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(kBuiltinPBE); i++) { |
322 | if (kBuiltinPBE[i].pbe_nid == pbe_nid && |
323 | // If |cipher_func| or |md_func| are missing, this is a PBES2 scheme. |
324 | kBuiltinPBE[i].cipher_func != NULL && |
325 | kBuiltinPBE[i].md_func != NULL) { |
326 | return &kBuiltinPBE[i]; |
327 | } |
328 | } |
329 | |
330 | return NULL; |
331 | } |
332 | |
333 | int pkcs12_pbe_encrypt_init(CBB *out, EVP_CIPHER_CTX *ctx, int alg, |
334 | unsigned iterations, const char *pass, |
335 | size_t pass_len, const uint8_t *salt, |
336 | size_t salt_len) { |
337 | const struct pbe_suite *suite = get_pkcs12_pbe_suite(alg); |
338 | if (suite == NULL) { |
339 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNKNOWN_ALGORITHM); |
340 | return 0; |
341 | } |
342 | |
343 | // See RFC 2898, appendix A.3. |
344 | CBB algorithm, oid, param, salt_cbb; |
345 | if (!CBB_add_asn1(out, &algorithm, CBS_ASN1_SEQUENCE) || |
346 | !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || |
347 | !CBB_add_bytes(&oid, suite->oid, suite->oid_len) || |
348 | !CBB_add_asn1(&algorithm, ¶m, CBS_ASN1_SEQUENCE) || |
349 | !CBB_add_asn1(¶m, &salt_cbb, CBS_ASN1_OCTETSTRING) || |
350 | !CBB_add_bytes(&salt_cbb, salt, salt_len) || |
351 | !CBB_add_asn1_uint64(¶m, iterations) || |
352 | !CBB_flush(out)) { |
353 | return 0; |
354 | } |
355 | |
356 | return pkcs12_pbe_cipher_init(suite, ctx, iterations, pass, pass_len, salt, |
357 | salt_len, 1 /* encrypt */); |
358 | } |
359 | |
360 | int pkcs8_pbe_decrypt(uint8_t **out, size_t *out_len, CBS *algorithm, |
361 | const char *pass, size_t pass_len, const uint8_t *in, |
362 | size_t in_len) { |
363 | int ret = 0; |
364 | uint8_t *buf = NULL;; |
365 | EVP_CIPHER_CTX ctx; |
366 | EVP_CIPHER_CTX_init(&ctx); |
367 | |
368 | CBS obj; |
369 | if (!CBS_get_asn1(algorithm, &obj, CBS_ASN1_OBJECT)) { |
370 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); |
371 | goto err; |
372 | } |
373 | |
374 | const struct pbe_suite *suite = NULL; |
375 | for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(kBuiltinPBE); i++) { |
376 | if (CBS_mem_equal(&obj, kBuiltinPBE[i].oid, kBuiltinPBE[i].oid_len)) { |
377 | suite = &kBuiltinPBE[i]; |
378 | break; |
379 | } |
380 | } |
381 | if (suite == NULL) { |
382 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNKNOWN_ALGORITHM); |
383 | goto err; |
384 | } |
385 | |
386 | if (!suite->decrypt_init(suite, &ctx, pass, pass_len, algorithm)) { |
387 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_KEYGEN_FAILURE); |
388 | goto err; |
389 | } |
390 | |
391 | buf = OPENSSL_malloc(in_len); |
392 | if (buf == NULL) { |
393 | OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); |
394 | goto err; |
395 | } |
396 | |
397 | if (in_len > INT_MAX) { |
398 | OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW); |
399 | goto err; |
400 | } |
401 | |
402 | int n1, n2; |
403 | if (!EVP_DecryptUpdate(&ctx, buf, &n1, in, (int)in_len) || |
404 | !EVP_DecryptFinal_ex(&ctx, buf + n1, &n2)) { |
405 | goto err; |
406 | } |
407 | |
408 | *out = buf; |
409 | *out_len = n1 + n2; |
410 | ret = 1; |
411 | buf = NULL; |
412 | |
413 | err: |
414 | OPENSSL_free(buf); |
415 | EVP_CIPHER_CTX_cleanup(&ctx); |
416 | return ret; |
417 | } |
418 | |
419 | EVP_PKEY *PKCS8_parse_encrypted_private_key(CBS *cbs, const char *pass, |
420 | size_t pass_len) { |
421 | // See RFC 5208, section 6. |
422 | CBS epki, algorithm, ciphertext; |
423 | if (!CBS_get_asn1(cbs, &epki, CBS_ASN1_SEQUENCE) || |
424 | !CBS_get_asn1(&epki, &algorithm, CBS_ASN1_SEQUENCE) || |
425 | !CBS_get_asn1(&epki, &ciphertext, CBS_ASN1_OCTETSTRING) || |
426 | CBS_len(&epki) != 0) { |
427 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); |
428 | return 0; |
429 | } |
430 | |
431 | uint8_t *out; |
432 | size_t out_len; |
433 | if (!pkcs8_pbe_decrypt(&out, &out_len, &algorithm, pass, pass_len, |
434 | CBS_data(&ciphertext), CBS_len(&ciphertext))) { |
435 | return 0; |
436 | } |
437 | |
438 | CBS pki; |
439 | CBS_init(&pki, out, out_len); |
440 | EVP_PKEY *ret = EVP_parse_private_key(&pki); |
441 | OPENSSL_free(out); |
442 | return ret; |
443 | } |
444 | |
445 | int PKCS8_marshal_encrypted_private_key(CBB *out, int pbe_nid, |
446 | const EVP_CIPHER *cipher, |
447 | const char *pass, size_t pass_len, |
448 | const uint8_t *salt, size_t salt_len, |
449 | int iterations, const EVP_PKEY *pkey) { |
450 | int ret = 0; |
451 | uint8_t *plaintext = NULL, *salt_buf = NULL; |
452 | size_t plaintext_len = 0; |
453 | EVP_CIPHER_CTX ctx; |
454 | EVP_CIPHER_CTX_init(&ctx); |
455 | |
456 | // Generate a random salt if necessary. |
457 | if (salt == NULL) { |
458 | if (salt_len == 0) { |
459 | salt_len = PKCS5_SALT_LEN; |
460 | } |
461 | |
462 | salt_buf = OPENSSL_malloc(salt_len); |
463 | if (salt_buf == NULL || |
464 | !RAND_bytes(salt_buf, salt_len)) { |
465 | goto err; |
466 | } |
467 | |
468 | salt = salt_buf; |
469 | } |
470 | |
471 | if (iterations <= 0) { |
472 | iterations = PKCS5_DEFAULT_ITERATIONS; |
473 | } |
474 | |
475 | // Serialize the input key. |
476 | CBB plaintext_cbb; |
477 | if (!CBB_init(&plaintext_cbb, 128) || |
478 | !EVP_marshal_private_key(&plaintext_cbb, pkey) || |
479 | !CBB_finish(&plaintext_cbb, &plaintext, &plaintext_len)) { |
480 | CBB_cleanup(&plaintext_cbb); |
481 | goto err; |
482 | } |
483 | |
484 | CBB epki; |
485 | if (!CBB_add_asn1(out, &epki, CBS_ASN1_SEQUENCE)) { |
486 | goto err; |
487 | } |
488 | |
489 | // TODO(davidben): OpenSSL has since extended |pbe_nid| to control either the |
490 | // PBES1 scheme or the PBES2 PRF. E.g. passing |NID_hmacWithSHA256| will |
491 | // select PBES2 with HMAC-SHA256 as the PRF. Implement this if anything uses |
492 | // it. See 5693a30813a031d3921a016a870420e7eb93ec90 in OpenSSL. |
493 | int alg_ok; |
494 | if (pbe_nid == -1) { |
495 | alg_ok = PKCS5_pbe2_encrypt_init(&epki, &ctx, cipher, (unsigned)iterations, |
496 | pass, pass_len, salt, salt_len); |
497 | } else { |
498 | alg_ok = pkcs12_pbe_encrypt_init(&epki, &ctx, pbe_nid, (unsigned)iterations, |
499 | pass, pass_len, salt, salt_len); |
500 | } |
501 | if (!alg_ok) { |
502 | goto err; |
503 | } |
504 | |
505 | size_t max_out = plaintext_len + EVP_CIPHER_CTX_block_size(&ctx); |
506 | if (max_out < plaintext_len) { |
507 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_TOO_LONG); |
508 | goto err; |
509 | } |
510 | |
511 | CBB ciphertext; |
512 | uint8_t *ptr; |
513 | int n1, n2; |
514 | if (!CBB_add_asn1(&epki, &ciphertext, CBS_ASN1_OCTETSTRING) || |
515 | !CBB_reserve(&ciphertext, &ptr, max_out) || |
516 | !EVP_CipherUpdate(&ctx, ptr, &n1, plaintext, plaintext_len) || |
517 | !EVP_CipherFinal_ex(&ctx, ptr + n1, &n2) || |
518 | !CBB_did_write(&ciphertext, n1 + n2) || |
519 | !CBB_flush(out)) { |
520 | goto err; |
521 | } |
522 | |
523 | ret = 1; |
524 | |
525 | err: |
526 | OPENSSL_free(plaintext); |
527 | OPENSSL_free(salt_buf); |
528 | EVP_CIPHER_CTX_cleanup(&ctx); |
529 | return ret; |
530 | } |
531 | |