| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *  Privacy Enhanced Mail (PEM) decoding | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2020-09-05 12:53:20 +02:00
										 |  |  |  *  Copyright The Mbed TLS Contributors | 
					
						
							| 
									
										
										
										
											2024-01-30 14:09:13 +01:00
										 |  |  |  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-21 12:54:05 +01:00
										 |  |  | #include "common.h"
 | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "mbedtls/pem.h"
 | 
					
						
							|  |  |  | #include "mbedtls/base64.h"
 | 
					
						
							|  |  |  | #include "mbedtls/des.h"
 | 
					
						
							|  |  |  | #include "mbedtls/aes.h"
 | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  | #include "mbedtls/md.h"
 | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | #include "mbedtls/cipher.h"
 | 
					
						
							| 
									
										
										
										
											2018-06-07 16:25:01 +02:00
										 |  |  | #include "mbedtls/platform_util.h"
 | 
					
						
							| 
									
										
										
										
											2021-12-21 12:54:05 +01:00
										 |  |  | #include "mbedtls/error.h"
 | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "mbedtls/platform.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  | #if defined(MBEDTLS_USE_PSA_CRYPTO)
 | 
					
						
							|  |  |  | #include "psa/crypto.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_MD_CAN_MD5) &&  \
 | 
					
						
							|  |  |  |     defined(MBEDTLS_CIPHER_MODE_CBC) &&                             \ | 
					
						
							|  |  |  |     (defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C)) | 
					
						
							|  |  |  | #define PEM_RFC1421
 | 
					
						
							|  |  |  | #endif /* MBEDTLS_MD_CAN_MD5 &&
 | 
					
						
							|  |  |  |           MBEDTLS_CIPHER_MODE_CBC && | 
					
						
							|  |  |  |           ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | #if defined(MBEDTLS_PEM_PARSE_C)
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | void mbedtls_pem_init(mbedtls_pem_context *ctx) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     memset(ctx, 0, sizeof(mbedtls_pem_context)); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  | #if defined(PEM_RFC1421)
 | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Read a 16-byte hex string and convert it to binary | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | static int pem_get_iv(const unsigned char *s, unsigned char *iv, | 
					
						
							|  |  |  |                       size_t iv_len) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     size_t i, j, k; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     memset(iv, 0, iv_len); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < iv_len * 2; i++, s++) { | 
					
						
							|  |  |  |         if (*s >= '0' && *s <= '9') { | 
					
						
							|  |  |  |             j = *s - '0'; | 
					
						
							|  |  |  |         } else | 
					
						
							|  |  |  |         if (*s >= 'A' && *s <= 'F') { | 
					
						
							|  |  |  |             j = *s - '7'; | 
					
						
							|  |  |  |         } else | 
					
						
							|  |  |  |         if (*s >= 'a' && *s <= 'f') { | 
					
						
							|  |  |  |             j = *s - 'W'; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             return MBEDTLS_ERR_PEM_INVALID_ENC_IV; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         k = ((i & 1) != 0) ? j : j << 4; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         iv[i >> 1] = (unsigned char) (iv[i >> 1] | k); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | static int pem_pbkdf1(unsigned char *key, size_t keylen, | 
					
						
							|  |  |  |                       unsigned char *iv, | 
					
						
							|  |  |  |                       const unsigned char *pwd, size_t pwdlen) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  |     mbedtls_md_context_t md5_ctx; | 
					
						
							|  |  |  |     const mbedtls_md_info_t *md5_info; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     unsigned char md5sum[16]; | 
					
						
							|  |  |  |     size_t use_len; | 
					
						
							| 
									
										
										
										
											2021-12-21 12:54:05 +01:00
										 |  |  |     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  |     mbedtls_md_init(&md5_ctx); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Prepare the context. (setup() errors gracefully on NULL info.) */ | 
					
						
							|  |  |  |     md5_info = mbedtls_md_info_from_type(MBEDTLS_MD_MD5); | 
					
						
							|  |  |  |     if ((ret = mbedtls_md_setup(&md5_ctx, md5_info, 0)) != 0) { | 
					
						
							|  |  |  |         goto exit; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * key[ 0..15] = MD5(pwd || IV) | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  |     if ((ret = mbedtls_md_starts(&md5_ctx)) != 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         goto exit; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  |     if ((ret = mbedtls_md_update(&md5_ctx, pwd, pwdlen)) != 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         goto exit; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  |     if ((ret = mbedtls_md_update(&md5_ctx, iv,  8)) != 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         goto exit; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  |     if ((ret = mbedtls_md_finish(&md5_ctx, md5sum)) != 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         goto exit; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (keylen <= 16) { | 
					
						
							|  |  |  |         memcpy(key, md5sum, keylen); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         goto exit; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     memcpy(key, md5sum, 16); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * key[16..23] = MD5(key[ 0..15] || pwd || IV]) | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  |     if ((ret = mbedtls_md_starts(&md5_ctx)) != 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         goto exit; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  |     if ((ret = mbedtls_md_update(&md5_ctx, md5sum, 16)) != 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         goto exit; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  |     if ((ret = mbedtls_md_update(&md5_ctx, pwd, pwdlen)) != 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         goto exit; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  |     if ((ret = mbedtls_md_update(&md5_ctx, iv, 8)) != 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         goto exit; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  |     if ((ret = mbedtls_md_finish(&md5_ctx, md5sum)) != 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         goto exit; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     use_len = 16; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (keylen < 32) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         use_len = keylen - 16; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     memcpy(key + 16, md5sum, use_len); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | exit: | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  |     mbedtls_md_free(&md5_ctx); | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_platform_zeroize(md5sum, 16); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     return ret; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_DES_C)
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Decrypt with DES-CBC, using PBKDF1 for key derivation | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | static int pem_des_decrypt(unsigned char des_iv[8], | 
					
						
							|  |  |  |                            unsigned char *buf, size_t buflen, | 
					
						
							|  |  |  |                            const unsigned char *pwd, size_t pwdlen) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     mbedtls_des_context des_ctx; | 
					
						
							|  |  |  |     unsigned char des_key[8]; | 
					
						
							| 
									
										
										
										
											2021-12-21 12:54:05 +01:00
										 |  |  |     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_des_init(&des_ctx); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = pem_pbkdf1(des_key, 8, des_iv, pwd, pwdlen)) != 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         goto exit; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_des_setkey_dec(&des_ctx, des_key)) != 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         goto exit; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     ret = mbedtls_des_crypt_cbc(&des_ctx, MBEDTLS_DES_DECRYPT, buflen, | 
					
						
							|  |  |  |                                 des_iv, buf, buf); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | exit: | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_des_free(&des_ctx); | 
					
						
							|  |  |  |     mbedtls_platform_zeroize(des_key, 8); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     return ret; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Decrypt with 3DES-CBC, using PBKDF1 for key derivation | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | static int pem_des3_decrypt(unsigned char des3_iv[8], | 
					
						
							|  |  |  |                             unsigned char *buf, size_t buflen, | 
					
						
							|  |  |  |                             const unsigned char *pwd, size_t pwdlen) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     mbedtls_des3_context des3_ctx; | 
					
						
							|  |  |  |     unsigned char des3_key[24]; | 
					
						
							| 
									
										
										
										
											2021-12-21 12:54:05 +01:00
										 |  |  |     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_des3_init(&des3_ctx); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = pem_pbkdf1(des3_key, 24, des3_iv, pwd, pwdlen)) != 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         goto exit; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_des3_set3key_dec(&des3_ctx, des3_key)) != 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         goto exit; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     ret = mbedtls_des3_crypt_cbc(&des3_ctx, MBEDTLS_DES_DECRYPT, buflen, | 
					
						
							|  |  |  |                                  des3_iv, buf, buf); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | exit: | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_des3_free(&des3_ctx); | 
					
						
							|  |  |  |     mbedtls_platform_zeroize(des3_key, 24); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     return ret; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | } | 
					
						
							|  |  |  | #endif /* MBEDTLS_DES_C */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_AES_C)
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Decrypt with AES-XXX-CBC, using PBKDF1 for key derivation | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | static int pem_aes_decrypt(unsigned char aes_iv[16], unsigned int keylen, | 
					
						
							|  |  |  |                            unsigned char *buf, size_t buflen, | 
					
						
							|  |  |  |                            const unsigned char *pwd, size_t pwdlen) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     mbedtls_aes_context aes_ctx; | 
					
						
							|  |  |  |     unsigned char aes_key[32]; | 
					
						
							| 
									
										
										
										
											2021-12-21 12:54:05 +01:00
										 |  |  |     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_aes_init(&aes_ctx); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = pem_pbkdf1(aes_key, keylen, aes_iv, pwd, pwdlen)) != 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         goto exit; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_aes_setkey_dec(&aes_ctx, aes_key, keylen * 8)) != 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         goto exit; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     ret = mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_DECRYPT, buflen, | 
					
						
							|  |  |  |                                 aes_iv, buf, buf); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | exit: | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_aes_free(&aes_ctx); | 
					
						
							|  |  |  |     mbedtls_platform_zeroize(aes_key, keylen); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     return ret; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | } | 
					
						
							|  |  |  | #endif /* MBEDTLS_AES_C */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  | #if defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C)
 | 
					
						
							|  |  |  | static int pem_check_pkcs_padding(unsigned char *input, size_t input_len, size_t *data_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /* input_len > 0 is guaranteed by mbedtls_pem_read_buffer(). */ | 
					
						
							|  |  |  |     size_t pad_len = input[input_len - 1]; | 
					
						
							|  |  |  |     size_t i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (pad_len > input_len) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PEM_PASSWORD_MISMATCH; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     *data_len = input_len - pad_len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = *data_len; i < input_len; i++) { | 
					
						
							|  |  |  |         if (input[i] != pad_len) { | 
					
						
							|  |  |  |             return MBEDTLS_ERR_PEM_PASSWORD_MISMATCH; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif /* MBEDTLS_DES_C || MBEDTLS_AES_C */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /* PEM_RFC1421 */
 | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | int mbedtls_pem_read_buffer(mbedtls_pem_context *ctx, const char *header, const char *footer, | 
					
						
							|  |  |  |                             const unsigned char *data, const unsigned char *pwd, | 
					
						
							|  |  |  |                             size_t pwdlen, size_t *use_len) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     int ret, enc; | 
					
						
							|  |  |  |     size_t len; | 
					
						
							|  |  |  |     unsigned char *buf; | 
					
						
							|  |  |  |     const unsigned char *s1, *s2, *end; | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  | #if defined(PEM_RFC1421)
 | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     unsigned char pem_iv[16]; | 
					
						
							|  |  |  |     mbedtls_cipher_type_t enc_alg = MBEDTLS_CIPHER_NONE; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     ((void) pwd); | 
					
						
							|  |  |  |     ((void) pwdlen); | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  | #endif /* PEM_RFC1421 */
 | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (ctx == NULL) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PEM_BAD_INPUT_DATA; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     s1 = (unsigned char *) strstr((const char *) data, header); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (s1 == NULL) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     s2 = (unsigned char *) strstr((const char *) data, footer); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (s2 == NULL || s2 <= s1) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     s1 += strlen(header); | 
					
						
							|  |  |  |     if (*s1 == ' ') { | 
					
						
							|  |  |  |         s1++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (*s1 == '\r') { | 
					
						
							|  |  |  |         s1++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (*s1 == '\n') { | 
					
						
							|  |  |  |         s1++; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     end = s2; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     end += strlen(footer); | 
					
						
							|  |  |  |     if (*end == ' ') { | 
					
						
							|  |  |  |         end++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (*end == '\r') { | 
					
						
							|  |  |  |         end++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (*end == '\n') { | 
					
						
							|  |  |  |         end++; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  |     *use_len = (size_t) (end - data); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     enc = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (s2 - s1 >= 22 && memcmp(s1, "Proc-Type: 4,ENCRYPTED", 22) == 0) { | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  | #if defined(PEM_RFC1421)
 | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         enc++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         s1 += 22; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         if (*s1 == '\r') { | 
					
						
							|  |  |  |             s1++; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (*s1 == '\n') { | 
					
						
							|  |  |  |             s1++; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             return MBEDTLS_ERR_PEM_INVALID_DATA; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_DES_C)
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         if (s2 - s1 >= 23 && memcmp(s1, "DEK-Info: DES-EDE3-CBC,", 23) == 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |             enc_alg = MBEDTLS_CIPHER_DES_EDE3_CBC; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             s1 += 23; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |             if (s2 - s1 < 16 || pem_get_iv(s1, pem_iv, 8) != 0) { | 
					
						
							|  |  |  |                 return MBEDTLS_ERR_PEM_INVALID_ENC_IV; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             s1 += 16; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         } else if (s2 - s1 >= 18 && memcmp(s1, "DEK-Info: DES-CBC,", 18) == 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |             enc_alg = MBEDTLS_CIPHER_DES_CBC; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             s1 += 18; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |             if (s2 - s1 < 16 || pem_get_iv(s1, pem_iv, 8) != 0) { | 
					
						
							|  |  |  |                 return MBEDTLS_ERR_PEM_INVALID_ENC_IV; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             s1 += 16; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | #endif /* MBEDTLS_DES_C */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_AES_C)
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         if (s2 - s1 >= 14 && memcmp(s1, "DEK-Info: AES-", 14) == 0) { | 
					
						
							|  |  |  |             if (s2 - s1 < 22) { | 
					
						
							|  |  |  |                 return MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG; | 
					
						
							|  |  |  |             } else if (memcmp(s1, "DEK-Info: AES-128-CBC,", 22) == 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |                 enc_alg = MBEDTLS_CIPHER_AES_128_CBC; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |             } else if (memcmp(s1, "DEK-Info: AES-192-CBC,", 22) == 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |                 enc_alg = MBEDTLS_CIPHER_AES_192_CBC; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |             } else if (memcmp(s1, "DEK-Info: AES-256-CBC,", 22) == 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |                 enc_alg = MBEDTLS_CIPHER_AES_256_CBC; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |             } else { | 
					
						
							|  |  |  |                 return MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             s1 += 22; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |             if (s2 - s1 < 32 || pem_get_iv(s1, pem_iv, 16) != 0) { | 
					
						
							|  |  |  |                 return MBEDTLS_ERR_PEM_INVALID_ENC_IV; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             s1 += 32; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | #endif /* MBEDTLS_AES_C */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         if (enc_alg == MBEDTLS_CIPHER_NONE) { | 
					
						
							|  |  |  |             return MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         if (*s1 == '\r') { | 
					
						
							|  |  |  |             s1++; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (*s1 == '\n') { | 
					
						
							|  |  |  |             s1++; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             return MBEDTLS_ERR_PEM_INVALID_DATA; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         return MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE; | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  | #endif /* PEM_RFC1421 */
 | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (s1 >= s2) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PEM_INVALID_DATA; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  |     ret = mbedtls_base64_decode(NULL, 0, &len, s1, (size_t) (s2 - s1)); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (ret == MBEDTLS_ERR_BASE64_INVALID_CHARACTER) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PEM_INVALID_DATA, ret); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  |     if (len == 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PEM_BAD_INPUT_DATA; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((buf = mbedtls_calloc(1, len)) == NULL) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PEM_ALLOC_FAILED; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  |     if ((ret = mbedtls_base64_decode(buf, len, &len, s1, (size_t) (s2 - s1))) != 0) { | 
					
						
							|  |  |  |         mbedtls_zeroize_and_free(buf, len); | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PEM_INVALID_DATA, ret); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (enc != 0) { | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  | #if defined(PEM_RFC1421)
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         if (pwd == NULL) { | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  |             mbedtls_zeroize_and_free(buf, len); | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |             return MBEDTLS_ERR_PEM_PASSWORD_REQUIRED; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ret = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_DES_C)
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         if (enc_alg == MBEDTLS_CIPHER_DES_EDE3_CBC) { | 
					
						
							|  |  |  |             ret = pem_des3_decrypt(pem_iv, buf, len, pwd, pwdlen); | 
					
						
							|  |  |  |         } else if (enc_alg == MBEDTLS_CIPHER_DES_CBC) { | 
					
						
							|  |  |  |             ret = pem_des_decrypt(pem_iv, buf, len, pwd, pwdlen); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | #endif /* MBEDTLS_DES_C */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_AES_C)
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         if (enc_alg == MBEDTLS_CIPHER_AES_128_CBC) { | 
					
						
							|  |  |  |             ret = pem_aes_decrypt(pem_iv, 16, buf, len, pwd, pwdlen); | 
					
						
							|  |  |  |         } else if (enc_alg == MBEDTLS_CIPHER_AES_192_CBC) { | 
					
						
							|  |  |  |             ret = pem_aes_decrypt(pem_iv, 24, buf, len, pwd, pwdlen); | 
					
						
							|  |  |  |         } else if (enc_alg == MBEDTLS_CIPHER_AES_256_CBC) { | 
					
						
							|  |  |  |             ret = pem_aes_decrypt(pem_iv, 32, buf, len, pwd, pwdlen); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | #endif /* MBEDTLS_AES_C */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         if (ret != 0) { | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  |             mbedtls_zeroize_and_free(buf, len); | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |             return ret; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  |         /* Check PKCS padding and update data length based on padding info.
 | 
					
						
							|  |  |  |          * This can be used to detect invalid padding data and password | 
					
						
							|  |  |  |          * mismatches. */ | 
					
						
							|  |  |  |         size_t unpadded_len; | 
					
						
							|  |  |  |         ret = pem_check_pkcs_padding(buf, len, &unpadded_len); | 
					
						
							|  |  |  |         if (ret != 0) { | 
					
						
							|  |  |  |             mbedtls_zeroize_and_free(buf, len); | 
					
						
							|  |  |  |             return ret; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  |         len = unpadded_len; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  |         mbedtls_zeroize_and_free(buf, len); | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         return MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE; | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  | #endif /* PEM_RFC1421 */
 | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ctx->buf = buf; | 
					
						
							|  |  |  |     ctx->buflen = len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | void mbedtls_pem_free(mbedtls_pem_context *ctx) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-08-31 15:25:10 +02:00
										 |  |  |     if (ctx == NULL) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (ctx->buf != NULL) { | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  |         mbedtls_zeroize_and_free(ctx->buf, ctx->buflen); | 
					
						
							| 
									
										
										
										
											2019-02-16 17:19:46 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_free(ctx->info); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_pem_context)); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | } | 
					
						
							|  |  |  | #endif /* MBEDTLS_PEM_PARSE_C */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_PEM_WRITE_C)
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | int mbedtls_pem_write_buffer(const char *header, const char *footer, | 
					
						
							|  |  |  |                              const unsigned char *der_data, size_t der_len, | 
					
						
							|  |  |  |                              unsigned char *buf, size_t buf_len, size_t *olen) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-12-21 12:54:05 +01:00
										 |  |  |     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; | 
					
						
							| 
									
										
										
										
											2018-03-28 17:26:33 +02:00
										 |  |  |     unsigned char *encode_buf = NULL, *c, *p = buf; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     size_t len = 0, use_len, add_len = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_base64_encode(NULL, 0, &use_len, der_data, der_len); | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  |     add_len = strlen(header) + strlen(footer) + (((use_len > 2) ? (use_len - 2) : 0) / 64) + 1; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (use_len + add_len > buf_len) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         *olen = use_len + add_len; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (use_len != 0 && | 
					
						
							|  |  |  |         ((encode_buf = mbedtls_calloc(1, use_len)) == NULL)) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PEM_ALLOC_FAILED; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_base64_encode(encode_buf, use_len, &use_len, der_data, | 
					
						
							|  |  |  |                                      der_len)) != 0) { | 
					
						
							|  |  |  |         mbedtls_free(encode_buf); | 
					
						
							|  |  |  |         return ret; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     memcpy(p, header, strlen(header)); | 
					
						
							|  |  |  |     p += strlen(header); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     c = encode_buf; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     while (use_len) { | 
					
						
							|  |  |  |         len = (use_len > 64) ? 64 : use_len; | 
					
						
							|  |  |  |         memcpy(p, c, len); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         use_len -= len; | 
					
						
							|  |  |  |         p += len; | 
					
						
							|  |  |  |         c += len; | 
					
						
							|  |  |  |         *p++ = '\n'; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     memcpy(p, footer, strlen(footer)); | 
					
						
							|  |  |  |     p += strlen(footer); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     *p++ = '\0'; | 
					
						
							| 
									
										
										
										
											2023-09-24 20:04:06 -07:00
										 |  |  |     *olen = (size_t) (p - buf); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     /* Clean any remaining data previously written to the buffer */ | 
					
						
							|  |  |  |     memset(buf + *olen, 0, buf_len - *olen); | 
					
						
							| 
									
										
										
										
											2020-12-18 21:22:37 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_free(encode_buf); | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | } | 
					
						
							|  |  |  | #endif /* MBEDTLS_PEM_WRITE_C */
 | 
					
						
							|  |  |  | #endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */
 |