| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *  Public Key layer for parsing key files and structures | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2020-09-05 12:53:20 +02:00
										 |  |  |  *  Copyright The Mbed TLS Contributors | 
					
						
							| 
									
										
										
										
											2021-12-21 12:54:05 +01:00
										 |  |  |  *  SPDX-License-Identifier: Apache-2.0 | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |  * | 
					
						
							|  |  |  |  *  Licensed under the Apache License, Version 2.0 (the "License"); you may | 
					
						
							|  |  |  |  *  not use this file except in compliance with the License. | 
					
						
							|  |  |  |  *  You may obtain a copy of the License at | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | 
					
						
							|  |  |  |  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  *  See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  *  limitations under the License. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-21 12:54:05 +01:00
										 |  |  | #include "common.h"
 | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_PK_PARSE_C)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "mbedtls/pk.h"
 | 
					
						
							|  |  |  | #include "mbedtls/asn1.h"
 | 
					
						
							|  |  |  | #include "mbedtls/oid.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>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_RSA_C)
 | 
					
						
							|  |  |  | #include "mbedtls/rsa.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_ECP_C)
 | 
					
						
							|  |  |  | #include "mbedtls/ecp.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_ECDSA_C)
 | 
					
						
							|  |  |  | #include "mbedtls/ecdsa.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_PEM_PARSE_C)
 | 
					
						
							|  |  |  | #include "mbedtls/pem.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_PKCS5_C)
 | 
					
						
							|  |  |  | #include "mbedtls/pkcs5.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_PKCS12_C)
 | 
					
						
							|  |  |  | #include "mbedtls/pkcs12.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "mbedtls/platform.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-16 17:19:46 +01:00
										 |  |  | /* Parameter validation macros based on platform_util.h */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | #define PK_VALIDATE_RET(cond)    \
 | 
					
						
							|  |  |  |     MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA) | 
					
						
							|  |  |  | #define PK_VALIDATE(cond)        \
 | 
					
						
							|  |  |  |     MBEDTLS_INTERNAL_VALIDATE(cond) | 
					
						
							| 
									
										
										
										
											2019-02-16 17:19:46 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | #if defined(MBEDTLS_FS_IO)
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Load all data from a file into a given buffer. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The file is expected to contain either PEM or DER encoded data. | 
					
						
							|  |  |  |  * A terminating null byte is always appended. It is included in the announced | 
					
						
							|  |  |  |  * length only if the data looks like it is PEM encoded. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | int mbedtls_pk_load_file(const char *path, unsigned char **buf, size_t *n) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     FILE *f; | 
					
						
							|  |  |  |     long size; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     PK_VALIDATE_RET(path != NULL); | 
					
						
							|  |  |  |     PK_VALIDATE_RET(buf != NULL); | 
					
						
							|  |  |  |     PK_VALIDATE_RET(n != NULL); | 
					
						
							| 
									
										
										
										
											2019-02-16 17:19:46 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((f = fopen(path, "rb")) == NULL) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_FILE_IO_ERROR; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     fseek(f, 0, SEEK_END); | 
					
						
							|  |  |  |     if ((size = ftell(f)) == -1) { | 
					
						
							|  |  |  |         fclose(f); | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_FILE_IO_ERROR; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     fseek(f, 0, SEEK_SET); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     *n = (size_t) size; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (*n + 1 == 0 || | 
					
						
							|  |  |  |         (*buf = mbedtls_calloc(1, *n + 1)) == NULL) { | 
					
						
							|  |  |  |         fclose(f); | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_ALLOC_FAILED; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (fread(*buf, 1, *n, f) != *n) { | 
					
						
							|  |  |  |         fclose(f); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         mbedtls_platform_zeroize(*buf, *n); | 
					
						
							|  |  |  |         mbedtls_free(*buf); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         return MBEDTLS_ERR_PK_FILE_IO_ERROR; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     fclose(f); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     (*buf)[*n] = '\0'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (strstr((const char *) *buf, "-----BEGIN ") != NULL) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         ++*n; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											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
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Load and parse a private key | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | int mbedtls_pk_parse_keyfile(mbedtls_pk_context *ctx, | 
					
						
							|  |  |  |                              const char *path, const char *pwd) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-12-21 12:54:05 +01:00
										 |  |  |     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     size_t n; | 
					
						
							|  |  |  |     unsigned char *buf; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     PK_VALIDATE_RET(ctx != NULL); | 
					
						
							|  |  |  |     PK_VALIDATE_RET(path != NULL); | 
					
						
							| 
									
										
										
										
											2019-02-16 17:19:46 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_pk_load_file(path, &buf, &n)) != 0) { | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (pwd == NULL) { | 
					
						
							|  |  |  |         ret = mbedtls_pk_parse_key(ctx, buf, n, NULL, 0); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         ret = mbedtls_pk_parse_key(ctx, buf, n, | 
					
						
							|  |  |  |                                    (const unsigned char *) pwd, strlen(pwd)); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_platform_zeroize(buf, n); | 
					
						
							|  |  |  |     mbedtls_free(buf); | 
					
						
							| 
									
										
										
										
											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
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Load and parse a public key | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | int mbedtls_pk_parse_public_keyfile(mbedtls_pk_context *ctx, const char *path) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-12-21 12:54:05 +01:00
										 |  |  |     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     size_t n; | 
					
						
							|  |  |  |     unsigned char *buf; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     PK_VALIDATE_RET(ctx != NULL); | 
					
						
							|  |  |  |     PK_VALIDATE_RET(path != NULL); | 
					
						
							| 
									
										
										
										
											2019-02-16 17:19:46 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_pk_load_file(path, &buf, &n)) != 0) { | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     ret = mbedtls_pk_parse_public_key(ctx, buf, n); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_platform_zeroize(buf, n); | 
					
						
							|  |  |  |     mbedtls_free(buf); | 
					
						
							| 
									
										
										
										
											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_FS_IO */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_ECP_C)
 | 
					
						
							|  |  |  | /* Minimally parse an ECParameters buffer to and mbedtls_asn1_buf
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ECParameters ::= CHOICE { | 
					
						
							|  |  |  |  *   namedCurve         OBJECT IDENTIFIER | 
					
						
							|  |  |  |  *   specifiedCurve     SpecifiedECDomain -- = SEQUENCE { ... } | 
					
						
							|  |  |  |  *   -- implicitCurve   NULL | 
					
						
							|  |  |  |  * } | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | static int pk_get_ecparams(unsigned char **p, const unsigned char *end, | 
					
						
							|  |  |  |                            mbedtls_asn1_buf *params) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											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
										 |  |  |     if (end - *p < 1) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, | 
					
						
							|  |  |  |                                  MBEDTLS_ERR_ASN1_OUT_OF_DATA); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-03-28 17:26:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     /* Tag may be either OID or SEQUENCE */ | 
					
						
							|  |  |  |     params->tag = **p; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (params->tag != MBEDTLS_ASN1_OID | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | #if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         && params->tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         ) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, | 
					
						
							|  |  |  |                                  MBEDTLS_ERR_ASN1_UNEXPECTED_TAG); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_tag(p, end, ¶ms->len, params->tag)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     params->p = *p; | 
					
						
							|  |  |  |     *p += params->len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (*p != end) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, | 
					
						
							|  |  |  |                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											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
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it. | 
					
						
							|  |  |  |  * WARNING: the resulting group should only be used with | 
					
						
							|  |  |  |  * pk_group_id_from_specified(), since its base point may not be set correctly | 
					
						
							|  |  |  |  * if it was encoded compressed. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  SpecifiedECDomain ::= SEQUENCE { | 
					
						
							|  |  |  |  *      version SpecifiedECDomainVersion(ecdpVer1 | ecdpVer2 | ecdpVer3, ...), | 
					
						
							|  |  |  |  *      fieldID FieldID {{FieldTypes}}, | 
					
						
							|  |  |  |  *      curve Curve, | 
					
						
							|  |  |  |  *      base ECPoint, | 
					
						
							|  |  |  |  *      order INTEGER, | 
					
						
							|  |  |  |  *      cofactor INTEGER OPTIONAL, | 
					
						
							|  |  |  |  *      hash HashAlgorithm OPTIONAL, | 
					
						
							|  |  |  |  *      ... | 
					
						
							|  |  |  |  *  } | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * We only support prime-field as field type, and ignore hash and cofactor. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | static int pk_group_from_specified(const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-12-21 12:54:05 +01:00
										 |  |  |     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     unsigned char *p = params->p; | 
					
						
							|  |  |  |     const unsigned char * const end = params->p + params->len; | 
					
						
							|  |  |  |     const unsigned char *end_field, *end_curve; | 
					
						
							|  |  |  |     size_t len; | 
					
						
							|  |  |  |     int ver; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_int(&p, end, &ver)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (ver < 1 || ver > 3) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * FieldID { FIELD-ID:IOSet } ::= SEQUENCE { -- Finite field | 
					
						
							|  |  |  |      *       fieldType FIELD-ID.&id({IOSet}), | 
					
						
							|  |  |  |      *       parameters FIELD-ID.&Type({IOSet}{@fieldType}) | 
					
						
							|  |  |  |      * } | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_tag(&p, end, &len, | 
					
						
							|  |  |  |                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     end_field = p + len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * FIELD-ID ::= TYPE-IDENTIFIER | 
					
						
							|  |  |  |      * FieldTypes FIELD-ID ::= { | 
					
						
							|  |  |  |      *       { Prime-p IDENTIFIED BY prime-field } | | 
					
						
							|  |  |  |      *       { Characteristic-two IDENTIFIED BY characteristic-two-field } | 
					
						
							|  |  |  |      * } | 
					
						
							|  |  |  |      * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 } | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_tag(&p, end_field, &len, MBEDTLS_ASN1_OID)) != 0) { | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (len != MBEDTLS_OID_SIZE(MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD) || | 
					
						
							|  |  |  |         memcmp(p, MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD, len) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     p += len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Prime-p ::= INTEGER -- Field of size p. */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_mpi(&p, end_field, &grp->P)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     grp->pbits = mbedtls_mpi_bitlen(&grp->P); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (p != end_field) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, | 
					
						
							|  |  |  |                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * Curve ::= SEQUENCE { | 
					
						
							|  |  |  |      *       a FieldElement, | 
					
						
							|  |  |  |      *       b FieldElement, | 
					
						
							|  |  |  |      *       seed BIT STRING OPTIONAL | 
					
						
							|  |  |  |      *       -- Shall be present if used in SpecifiedECDomain | 
					
						
							|  |  |  |      *       -- with version equal to ecdpVer2 or ecdpVer3 | 
					
						
							|  |  |  |      * } | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_tag(&p, end, &len, | 
					
						
							|  |  |  |                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     end_curve = p + len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * FieldElement ::= OCTET STRING | 
					
						
							|  |  |  |      * containing an integer in the case of a prime field | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_tag(&p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0 || | 
					
						
							|  |  |  |         (ret = mbedtls_mpi_read_binary(&grp->A, p, len)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     p += len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_tag(&p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0 || | 
					
						
							|  |  |  |         (ret = mbedtls_mpi_read_binary(&grp->B, p, len)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     p += len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Ignore seed BIT STRING OPTIONAL */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_tag(&p, end_curve, &len, MBEDTLS_ASN1_BIT_STRING)) == 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         p += len; | 
					
						
							| 
									
										
										
										
											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 (p != end_curve) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, | 
					
						
							|  |  |  |                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * ECPoint ::= OCTET STRING | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_ecp_point_read_binary(grp, &grp->G, | 
					
						
							|  |  |  |                                              (const unsigned char *) p, len)) != 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         /*
 | 
					
						
							|  |  |  |          * If we can't read the point because it's compressed, cheat by | 
					
						
							|  |  |  |          * reading only the X coordinate and the parity bit of Y. | 
					
						
							|  |  |  |          */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         if (ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE || | 
					
						
							|  |  |  |             (p[0] != 0x02 && p[0] != 0x03) || | 
					
						
							|  |  |  |             len != mbedtls_mpi_size(&grp->P) + 1 || | 
					
						
							|  |  |  |             mbedtls_mpi_read_binary(&grp->G.X, p + 1, len - 1) != 0 || | 
					
						
							|  |  |  |             mbedtls_mpi_lset(&grp->G.Y, p[0] - 2) != 0 || | 
					
						
							|  |  |  |             mbedtls_mpi_lset(&grp->G.Z, 1) != 0) { | 
					
						
							|  |  |  |             return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     p += len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * order INTEGER | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_mpi(&p, end, &grp->N)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     grp->nbits = mbedtls_mpi_bitlen(&grp->N); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * Allow optional elements by purposefully not enforcing p == end here. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Find the group id associated with an (almost filled) group as generated by | 
					
						
							|  |  |  |  * pk_group_from_specified(), or return an error if unknown. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | static int pk_group_id_from_group(const mbedtls_ecp_group *grp, mbedtls_ecp_group_id *grp_id) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     int ret = 0; | 
					
						
							|  |  |  |     mbedtls_ecp_group ref; | 
					
						
							|  |  |  |     const mbedtls_ecp_group_id *id; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_ecp_group_init(&ref); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     for (id = mbedtls_ecp_grp_id_list(); *id != MBEDTLS_ECP_DP_NONE; id++) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         /* Load the group associated to that id */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         mbedtls_ecp_group_free(&ref); | 
					
						
							|  |  |  |         MBEDTLS_MPI_CHK(mbedtls_ecp_group_load(&ref, *id)); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         /* Compare to the group we were given, starting with easy tests */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         if (grp->pbits == ref.pbits && grp->nbits == ref.nbits && | 
					
						
							|  |  |  |             mbedtls_mpi_cmp_mpi(&grp->P, &ref.P) == 0 && | 
					
						
							|  |  |  |             mbedtls_mpi_cmp_mpi(&grp->A, &ref.A) == 0 && | 
					
						
							|  |  |  |             mbedtls_mpi_cmp_mpi(&grp->B, &ref.B) == 0 && | 
					
						
							|  |  |  |             mbedtls_mpi_cmp_mpi(&grp->N, &ref.N) == 0 && | 
					
						
							|  |  |  |             mbedtls_mpi_cmp_mpi(&grp->G.X, &ref.G.X) == 0 && | 
					
						
							|  |  |  |             mbedtls_mpi_cmp_mpi(&grp->G.Z, &ref.G.Z) == 0 && | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |             /* For Y we may only know the parity bit, so compare only that */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |             mbedtls_mpi_get_bit(&grp->G.Y, 0) == mbedtls_mpi_get_bit(&ref.G.Y, 0)) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | cleanup: | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_ecp_group_free(&ref); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     *grp_id = *id; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (ret == 0 && *id == MBEDTLS_ECP_DP_NONE) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											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
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Parse a SpecifiedECDomain (SEC 1 C.2) and find the associated group ID | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | static int pk_group_id_from_specified(const mbedtls_asn1_buf *params, | 
					
						
							|  |  |  |                                       mbedtls_ecp_group_id *grp_id) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-12-21 12:54:05 +01:00
										 |  |  |     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     mbedtls_ecp_group grp; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_ecp_group_init(&grp); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = pk_group_from_specified(params, &grp)) != 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         goto cleanup; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     ret = pk_group_id_from_group(&grp, grp_id); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | cleanup: | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_ecp_group_free(&grp); | 
					
						
							| 
									
										
										
										
											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_PK_PARSE_EC_EXTENDED */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Use EC parameters to initialise an EC group | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ECParameters ::= CHOICE { | 
					
						
							|  |  |  |  *   namedCurve         OBJECT IDENTIFIER | 
					
						
							|  |  |  |  *   specifiedCurve     SpecifiedECDomain -- = SEQUENCE { ... } | 
					
						
							|  |  |  |  *   -- implicitCurve   NULL | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | static int pk_use_ecparams(const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-12-21 12:54:05 +01:00
										 |  |  |     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     mbedtls_ecp_group_id grp_id; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (params->tag == MBEDTLS_ASN1_OID) { | 
					
						
							|  |  |  |         if (mbedtls_oid_get_ec_grp(params, &grp_id) != 0) { | 
					
						
							|  |  |  |             return MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | #if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         if ((ret = pk_group_id_from_specified(params, &grp_id)) != 0) { | 
					
						
							|  |  |  |             return ret; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							| 
									
										
										
										
											2022-07-18 14:48:00 +02:00
										 |  |  |      * grp may already be initialized; if so, make sure IDs match | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (grp->id != MBEDTLS_ECP_DP_NONE && grp->id != grp_id) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_ecp_group_load(grp, grp_id)) != 0) { | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											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
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * EC public key is an EC point | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The caller is responsible for clearing the structure upon failure if | 
					
						
							|  |  |  |  * desired. Take care to pass along the possible ECP_FEATURE_UNAVAILABLE | 
					
						
							|  |  |  |  * return code of mbedtls_ecp_point_read_binary() and leave p in a usable state. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | static int pk_get_ecpubkey(unsigned char **p, const unsigned char *end, | 
					
						
							|  |  |  |                            mbedtls_ecp_keypair *key) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											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
										 |  |  |     if ((ret = mbedtls_ecp_point_read_binary(&key->grp, &key->Q, | 
					
						
							|  |  |  |                                              (const unsigned char *) *p, end - *p)) == 0) { | 
					
						
							|  |  |  |         ret = mbedtls_ecp_check_pubkey(&key->grp, &key->Q); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * We know mbedtls_ecp_point_read_binary consumed all bytes or failed | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     *p = (unsigned char *) end; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     return ret; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | } | 
					
						
							|  |  |  | #endif /* MBEDTLS_ECP_C */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_RSA_C)
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  *  RSAPublicKey ::= SEQUENCE { | 
					
						
							|  |  |  |  *      modulus           INTEGER,  -- n | 
					
						
							|  |  |  |  *      publicExponent    INTEGER   -- e | 
					
						
							|  |  |  |  *  } | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | static int pk_get_rsapubkey(unsigned char **p, | 
					
						
							|  |  |  |                             const unsigned char *end, | 
					
						
							|  |  |  |                             mbedtls_rsa_context *rsa) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-12-21 12:54:05 +01:00
										 |  |  |     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     size_t len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_tag(p, end, &len, | 
					
						
							|  |  |  |                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, ret); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (*p + len != end) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, | 
					
						
							|  |  |  |                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Import N */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, ret); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_rsa_import_raw(rsa, *p, len, NULL, 0, NULL, 0, | 
					
						
							|  |  |  |                                       NULL, 0, NULL, 0)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_INVALID_PUBKEY; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     *p += len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Import E */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, ret); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_rsa_import_raw(rsa, NULL, 0, NULL, 0, NULL, 0, | 
					
						
							|  |  |  |                                       NULL, 0, *p, len)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_INVALID_PUBKEY; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     *p += len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (mbedtls_rsa_complete(rsa) != 0 || | 
					
						
							|  |  |  |         mbedtls_rsa_check_pubkey(rsa) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_INVALID_PUBKEY; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (*p != end) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, | 
					
						
							|  |  |  |                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											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
										 |  |  | } | 
					
						
							|  |  |  | #endif /* MBEDTLS_RSA_C */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Get a PK algorithm identifier
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  AlgorithmIdentifier  ::=  SEQUENCE  { | 
					
						
							|  |  |  |  *       algorithm               OBJECT IDENTIFIER, | 
					
						
							|  |  |  |  *       parameters              ANY DEFINED BY algorithm OPTIONAL  } | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | static int pk_get_pk_alg(unsigned char **p, | 
					
						
							|  |  |  |                          const unsigned char *end, | 
					
						
							|  |  |  |                          mbedtls_pk_type_t *pk_alg, mbedtls_asn1_buf *params) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-12-21 12:54:05 +01:00
										 |  |  |     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     mbedtls_asn1_buf alg_oid; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     memset(params, 0, sizeof(mbedtls_asn1_buf)); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_alg(p, end, &alg_oid, params)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_ALG, ret); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (mbedtls_oid_get_pk_alg(&alg_oid, pk_alg) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_UNKNOWN_PK_ALG; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * No parameters with RSA (only for EC) | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (*pk_alg == MBEDTLS_PK_RSA && | 
					
						
							|  |  |  |         ((params->tag != MBEDTLS_ASN1_NULL && params->tag != 0) || | 
					
						
							|  |  |  |          params->len != 0)) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_INVALID_ALG; | 
					
						
							| 
									
										
										
										
											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
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  *  SubjectPublicKeyInfo  ::=  SEQUENCE  { | 
					
						
							|  |  |  |  *       algorithm            AlgorithmIdentifier, | 
					
						
							|  |  |  |  *       subjectPublicKey     BIT STRING } | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | int mbedtls_pk_parse_subpubkey(unsigned char **p, const unsigned char *end, | 
					
						
							|  |  |  |                                mbedtls_pk_context *pk) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-12-21 12:54:05 +01:00
										 |  |  |     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     size_t len; | 
					
						
							|  |  |  |     mbedtls_asn1_buf alg_params; | 
					
						
							|  |  |  |     mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; | 
					
						
							|  |  |  |     const mbedtls_pk_info_t *pk_info; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     PK_VALIDATE_RET(p != NULL); | 
					
						
							|  |  |  |     PK_VALIDATE_RET(*p != NULL); | 
					
						
							|  |  |  |     PK_VALIDATE_RET(end != NULL); | 
					
						
							|  |  |  |     PK_VALIDATE_RET(pk != NULL); | 
					
						
							| 
									
										
										
										
											2019-02-16 17:19:46 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_tag(p, end, &len, | 
					
						
							|  |  |  |                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     end = *p + len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = pk_get_pk_alg(p, end, &pk_alg, &alg_params)) != 0) { | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_bitstring_null(p, end, &len)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, ret); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (*p + len != end) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, | 
					
						
							|  |  |  |                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((pk_info = mbedtls_pk_info_from_type(pk_alg)) == NULL) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_UNKNOWN_PK_ALG; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_pk_setup(pk, pk_info)) != 0) { | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_RSA_C)
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (pk_alg == MBEDTLS_PK_RSA) { | 
					
						
							|  |  |  |         ret = pk_get_rsapubkey(p, end, mbedtls_pk_rsa(*pk)); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } else | 
					
						
							|  |  |  | #endif /* MBEDTLS_RSA_C */
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_ECP_C)
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (pk_alg == MBEDTLS_PK_ECKEY_DH || pk_alg == MBEDTLS_PK_ECKEY) { | 
					
						
							|  |  |  |         ret = pk_use_ecparams(&alg_params, &mbedtls_pk_ec(*pk)->grp); | 
					
						
							|  |  |  |         if (ret == 0) { | 
					
						
							|  |  |  |             ret = pk_get_ecpubkey(p, end, mbedtls_pk_ec(*pk)); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } else | 
					
						
							|  |  |  | #endif /* MBEDTLS_ECP_C */
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     ret = MBEDTLS_ERR_PK_UNKNOWN_PK_ALG; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (ret == 0 && *p != end) { | 
					
						
							|  |  |  |         ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, | 
					
						
							|  |  |  |                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (ret != 0) { | 
					
						
							|  |  |  |         mbedtls_pk_free(pk); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											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_RSA_C)
 | 
					
						
							| 
									
										
										
										
											2020-03-05 16:12:23 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Wrapper around mbedtls_asn1_get_mpi() that rejects zero. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The value zero is: | 
					
						
							|  |  |  |  * - never a valid value for an RSA parameter | 
					
						
							|  |  |  |  * - interpreted as "omitted, please reconstruct" by mbedtls_rsa_complete(). | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Since values can't be omitted in PKCS#1, passing a zero value to | 
					
						
							|  |  |  |  * rsa_complete() would be incorrect, so reject zero values early. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | static int asn1_get_nonzero_mpi(unsigned char **p, | 
					
						
							|  |  |  |                                 const unsigned char *end, | 
					
						
							|  |  |  |                                 mbedtls_mpi *X) | 
					
						
							| 
									
										
										
										
											2020-03-05 16:12:23 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     int ret; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     ret = mbedtls_asn1_get_mpi(p, end, X); | 
					
						
							|  |  |  |     if (ret != 0) { | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-03-05 16:12:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (mbedtls_mpi_cmp_int(X, 0) == 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-03-05 16:12:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2020-03-05 16:12:23 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Parse a PKCS#1 encoded private RSA key | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | static int pk_parse_key_pkcs1_der(mbedtls_rsa_context *rsa, | 
					
						
							|  |  |  |                                   const unsigned char *key, | 
					
						
							|  |  |  |                                   size_t keylen) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     int ret, version; | 
					
						
							|  |  |  |     size_t len; | 
					
						
							|  |  |  |     unsigned char *p, *end; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     mbedtls_mpi T; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_mpi_init(&T); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     p = (unsigned char *) key; | 
					
						
							|  |  |  |     end = p + keylen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * This function parses the RSAPrivateKey (PKCS#1) | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      *  RSAPrivateKey ::= SEQUENCE { | 
					
						
							|  |  |  |      *      version           Version, | 
					
						
							|  |  |  |      *      modulus           INTEGER,  -- n | 
					
						
							|  |  |  |      *      publicExponent    INTEGER,  -- e | 
					
						
							|  |  |  |      *      privateExponent   INTEGER,  -- d | 
					
						
							|  |  |  |      *      prime1            INTEGER,  -- p | 
					
						
							|  |  |  |      *      prime2            INTEGER,  -- q | 
					
						
							|  |  |  |      *      exponent1         INTEGER,  -- d mod (p-1) | 
					
						
							|  |  |  |      *      exponent2         INTEGER,  -- d mod (q-1) | 
					
						
							|  |  |  |      *      coefficient       INTEGER,  -- (inverse of q) mod p | 
					
						
							|  |  |  |      *      otherPrimeInfos   OtherPrimeInfos OPTIONAL | 
					
						
							|  |  |  |      *  } | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_tag(&p, end, &len, | 
					
						
							|  |  |  |                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     end = p + len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_int(&p, end, &version)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (version != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_KEY_INVALID_VERSION; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Import N */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || | 
					
						
							|  |  |  |         (ret = mbedtls_rsa_import(rsa, &T, NULL, NULL, | 
					
						
							|  |  |  |                                   NULL, NULL)) != 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         goto cleanup; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Import E */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || | 
					
						
							|  |  |  |         (ret = mbedtls_rsa_import(rsa, NULL, NULL, NULL, | 
					
						
							|  |  |  |                                   NULL, &T)) != 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         goto cleanup; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Import D */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || | 
					
						
							|  |  |  |         (ret = mbedtls_rsa_import(rsa, NULL, NULL, NULL, | 
					
						
							|  |  |  |                                   &T, NULL)) != 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         goto cleanup; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Import P */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || | 
					
						
							|  |  |  |         (ret = mbedtls_rsa_import(rsa, NULL, &T, NULL, | 
					
						
							|  |  |  |                                   NULL, NULL)) != 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         goto cleanup; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Import Q */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || | 
					
						
							|  |  |  |         (ret = mbedtls_rsa_import(rsa, NULL, NULL, &T, | 
					
						
							|  |  |  |                                   NULL, NULL)) != 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         goto cleanup; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-05 16:12:23 +01:00
										 |  |  | #if !defined(MBEDTLS_RSA_NO_CRT) && !defined(MBEDTLS_RSA_ALT)
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |      * The RSA CRT parameters DP, DQ and QP are nominally redundant, in | 
					
						
							|  |  |  |      * that they can be easily recomputed from D, P and Q. However by | 
					
						
							|  |  |  |      * parsing them from the PKCS1 structure it is possible to avoid | 
					
						
							|  |  |  |      * recalculating them which both reduces the overhead of loading | 
					
						
							|  |  |  |      * RSA private keys into memory and also avoids side channels which | 
					
						
							|  |  |  |      * can arise when computing those values, since all of D, P, and Q | 
					
						
							|  |  |  |      * are secret. See https://eprint.iacr.org/2020/055 for a
 | 
					
						
							|  |  |  |      * description of one such attack. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-03-05 16:12:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Import DP */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || | 
					
						
							|  |  |  |         (ret = mbedtls_mpi_copy(&rsa->DP, &T)) != 0) { | 
					
						
							|  |  |  |         goto cleanup; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-03-05 16:12:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Import DQ */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || | 
					
						
							|  |  |  |         (ret = mbedtls_mpi_copy(&rsa->DQ, &T)) != 0) { | 
					
						
							|  |  |  |         goto cleanup; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-03-05 16:12:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Import QP */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || | 
					
						
							|  |  |  |         (ret = mbedtls_mpi_copy(&rsa->QP, &T)) != 0) { | 
					
						
							|  |  |  |         goto cleanup; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-03-05 16:12:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2022-07-18 14:48:00 +02:00
										 |  |  |     /* Verify existence of the CRT params */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || | 
					
						
							|  |  |  |         (ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 || | 
					
						
							|  |  |  |         (ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0) { | 
					
						
							|  |  |  |         goto cleanup; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-03-05 16:12:23 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-05 16:12:23 +01:00
										 |  |  |     /* rsa_complete() doesn't complete anything with the default
 | 
					
						
							|  |  |  |      * implementation but is still called: | 
					
						
							|  |  |  |      * - for the benefit of alternative implementation that may want to | 
					
						
							|  |  |  |      *   pre-compute stuff beyond what's provided (eg Montgomery factors) | 
					
						
							|  |  |  |      * - as is also sanity-checks the key | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * Furthermore, we also check the public part for consistency with | 
					
						
							|  |  |  |      * mbedtls_pk_parse_pubkey(), as it includes size minima for example. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_rsa_complete(rsa)) != 0 || | 
					
						
							|  |  |  |         (ret = mbedtls_rsa_check_pubkey(rsa)) != 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         goto cleanup; | 
					
						
							| 
									
										
										
										
											2020-03-05 16:12:23 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (p != end) { | 
					
						
							|  |  |  |         ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, | 
					
						
							|  |  |  |                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | cleanup: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_mpi_free(&T); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (ret != 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         /* Wrap error code if it's coming from a lower level */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         if ((ret & 0xff80) == 0) { | 
					
						
							|  |  |  |             ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							|  |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |             ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         mbedtls_rsa_free(rsa); | 
					
						
							| 
									
										
										
										
											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_RSA_C */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_ECP_C)
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Parse a SEC1 encoded private EC key | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | static int pk_parse_key_sec1_der(mbedtls_ecp_keypair *eck, | 
					
						
							|  |  |  |                                  const unsigned char *key, | 
					
						
							|  |  |  |                                  size_t keylen) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-12-21 12:54:05 +01:00
										 |  |  |     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     int version, pubkey_done; | 
					
						
							|  |  |  |     size_t len; | 
					
						
							|  |  |  |     mbedtls_asn1_buf params; | 
					
						
							|  |  |  |     unsigned char *p = (unsigned char *) key; | 
					
						
							|  |  |  |     unsigned char *end = p + keylen; | 
					
						
							|  |  |  |     unsigned char *end2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * RFC 5915, or SEC1 Appendix C.4 | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * ECPrivateKey ::= SEQUENCE { | 
					
						
							|  |  |  |      *      version        INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), | 
					
						
							|  |  |  |      *      privateKey     OCTET STRING, | 
					
						
							|  |  |  |      *      parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, | 
					
						
							|  |  |  |      *      publicKey  [1] BIT STRING OPTIONAL | 
					
						
							|  |  |  |      *    } | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_tag(&p, end, &len, | 
					
						
							|  |  |  |                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     end = p + len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_int(&p, end, &version)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (version != 1) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_KEY_INVALID_VERSION; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_mpi_read_binary(&eck->d, p, len)) != 0) { | 
					
						
							|  |  |  |         mbedtls_ecp_keypair_free(eck); | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     p += len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     pubkey_done = 0; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (p != end) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         /*
 | 
					
						
							|  |  |  |          * Is 'parameters' present? | 
					
						
							|  |  |  |          */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         if ((ret = mbedtls_asn1_get_tag(&p, end, &len, | 
					
						
							|  |  |  |                                         MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | | 
					
						
							|  |  |  |                                         0)) == 0) { | 
					
						
							|  |  |  |             if ((ret = pk_get_ecparams(&p, p + len, ¶ms)) != 0 || | 
					
						
							|  |  |  |                 (ret = pk_use_ecparams(¶ms, &eck->grp)) != 0) { | 
					
						
							|  |  |  |                 mbedtls_ecp_keypair_free(eck); | 
					
						
							|  |  |  |                 return ret; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { | 
					
						
							|  |  |  |             mbedtls_ecp_keypair_free(eck); | 
					
						
							|  |  |  |             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-06-07 16:25:01 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (p != end) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         /*
 | 
					
						
							|  |  |  |          * Is 'publickey' present? If not, or if we can't read it (eg because it | 
					
						
							|  |  |  |          * is compressed), create it from the private key. | 
					
						
							|  |  |  |          */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         if ((ret = mbedtls_asn1_get_tag(&p, end, &len, | 
					
						
							|  |  |  |                                         MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | | 
					
						
							|  |  |  |                                         1)) == 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |             end2 = p + len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |             if ((ret = mbedtls_asn1_get_bitstring_null(&p, end2, &len)) != 0) { | 
					
						
							|  |  |  |                 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |             if (p + len != end2) { | 
					
						
							|  |  |  |                 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, | 
					
						
							|  |  |  |                                          MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |             if ((ret = pk_get_ecpubkey(&p, end2, eck)) == 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |                 pubkey_done = 1; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |                 /*
 | 
					
						
							|  |  |  |                  * The only acceptable failure mode of pk_get_ecpubkey() above | 
					
						
							|  |  |  |                  * is if the point format is not recognized. | 
					
						
							|  |  |  |                  */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |                 if (ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) { | 
					
						
							|  |  |  |                     return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { | 
					
						
							|  |  |  |             mbedtls_ecp_keypair_free(eck); | 
					
						
							|  |  |  |             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (!pubkey_done && | 
					
						
							|  |  |  |         (ret = mbedtls_ecp_mul(&eck->grp, &eck->Q, &eck->d, &eck->grp.G, | 
					
						
							|  |  |  |                                NULL, NULL)) != 0) { | 
					
						
							|  |  |  |         mbedtls_ecp_keypair_free(eck); | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_ecp_check_privkey(&eck->grp, &eck->d)) != 0) { | 
					
						
							|  |  |  |         mbedtls_ecp_keypair_free(eck); | 
					
						
							|  |  |  |         return ret; | 
					
						
							| 
									
										
										
										
											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
										 |  |  | } | 
					
						
							|  |  |  | #endif /* MBEDTLS_ECP_C */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Parse an unencrypted PKCS#8 encoded private key | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Notes: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * - This function does not own the key buffer. It is the | 
					
						
							|  |  |  |  *   responsibility of the caller to take care of zeroizing | 
					
						
							|  |  |  |  *   and freeing it after use. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * - The function is responsible for freeing the provided | 
					
						
							|  |  |  |  *   PK context on failure. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static int pk_parse_key_pkcs8_unencrypted_der( | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_pk_context *pk, | 
					
						
							|  |  |  |     const unsigned char *key, | 
					
						
							|  |  |  |     size_t keylen) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     int ret, version; | 
					
						
							|  |  |  |     size_t len; | 
					
						
							|  |  |  |     mbedtls_asn1_buf params; | 
					
						
							|  |  |  |     unsigned char *p = (unsigned char *) key; | 
					
						
							|  |  |  |     unsigned char *end = p + keylen; | 
					
						
							|  |  |  |     mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; | 
					
						
							|  |  |  |     const mbedtls_pk_info_t *pk_info; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * This function parses the PrivateKeyInfo object (PKCS#8 v1.2 = RFC 5208) | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      *    PrivateKeyInfo ::= SEQUENCE { | 
					
						
							|  |  |  |      *      version                   Version, | 
					
						
							|  |  |  |      *      privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier, | 
					
						
							|  |  |  |      *      privateKey                PrivateKey, | 
					
						
							|  |  |  |      *      attributes           [0]  IMPLICIT Attributes OPTIONAL } | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      *    Version ::= INTEGER | 
					
						
							|  |  |  |      *    PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier | 
					
						
							|  |  |  |      *    PrivateKey ::= OCTET STRING | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      *  The PrivateKey OCTET STRING is a SEC1 ECPrivateKey | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_tag(&p, end, &len, | 
					
						
							|  |  |  |                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     end = p + len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_int(&p, end, &version)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (version != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_VERSION, ret); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = pk_get_pk_alg(&p, end, &pk_alg, ¶ms)) != 0) { | 
					
						
							|  |  |  |         return ret; | 
					
						
							| 
									
										
										
										
											2021-12-21 12:54:05 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (len < 1) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, | 
					
						
							|  |  |  |                                  MBEDTLS_ERR_ASN1_OUT_OF_DATA); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((pk_info = mbedtls_pk_info_from_type(pk_alg)) == NULL) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_UNKNOWN_PK_ALG; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_pk_setup(pk, pk_info)) != 0) { | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_RSA_C)
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (pk_alg == MBEDTLS_PK_RSA) { | 
					
						
							|  |  |  |         if ((ret = pk_parse_key_pkcs1_der(mbedtls_pk_rsa(*pk), p, len)) != 0) { | 
					
						
							|  |  |  |             mbedtls_pk_free(pk); | 
					
						
							|  |  |  |             return ret; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } else | 
					
						
							|  |  |  | #endif /* MBEDTLS_RSA_C */
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_ECP_C)
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH) { | 
					
						
							|  |  |  |         if ((ret = pk_use_ecparams(¶ms, &mbedtls_pk_ec(*pk)->grp)) != 0 || | 
					
						
							|  |  |  |             (ret = pk_parse_key_sec1_der(mbedtls_pk_ec(*pk), p, len)) != 0) { | 
					
						
							|  |  |  |             mbedtls_pk_free(pk); | 
					
						
							|  |  |  |             return ret; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } else | 
					
						
							|  |  |  | #endif /* MBEDTLS_ECP_C */
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     return MBEDTLS_ERR_PK_UNKNOWN_PK_ALG; | 
					
						
							| 
									
										
										
										
											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
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Parse an encrypted PKCS#8 encoded private key | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * To save space, the decryption happens in-place on the given key buffer. | 
					
						
							|  |  |  |  * Also, while this function may modify the keybuffer, it doesn't own it, | 
					
						
							|  |  |  |  * and instead it is the responsibility of the caller to zeroize and properly | 
					
						
							|  |  |  |  * free it after use. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
 | 
					
						
							|  |  |  | static int pk_parse_key_pkcs8_encrypted_der( | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_pk_context *pk, | 
					
						
							|  |  |  |     unsigned char *key, size_t keylen, | 
					
						
							|  |  |  |     const unsigned char *pwd, size_t pwdlen) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     int ret, decrypted = 0; | 
					
						
							|  |  |  |     size_t len; | 
					
						
							|  |  |  |     unsigned char *buf; | 
					
						
							|  |  |  |     unsigned char *p, *end; | 
					
						
							|  |  |  |     mbedtls_asn1_buf pbe_alg_oid, pbe_params; | 
					
						
							|  |  |  | #if defined(MBEDTLS_PKCS12_C)
 | 
					
						
							|  |  |  |     mbedtls_cipher_type_t cipher_alg; | 
					
						
							|  |  |  |     mbedtls_md_type_t md_alg; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     p = key; | 
					
						
							|  |  |  |     end = p + keylen; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (pwdlen == 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_PASSWORD_REQUIRED; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * This function parses the EncryptedPrivateKeyInfo object (PKCS#8) | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      *  EncryptedPrivateKeyInfo ::= SEQUENCE { | 
					
						
							|  |  |  |      *    encryptionAlgorithm  EncryptionAlgorithmIdentifier, | 
					
						
							|  |  |  |      *    encryptedData        EncryptedData | 
					
						
							|  |  |  |      *  } | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      *  EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      *  EncryptedData ::= OCTET STRING | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      *  The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_tag(&p, end, &len, | 
					
						
							|  |  |  |                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     end = p + len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_alg(&p, end, &pbe_alg_oid, &pbe_params)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     buf = p; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * Decrypt EncryptedData with appropriate PBE | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  | #if defined(MBEDTLS_PKCS12_C)
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (mbedtls_oid_get_pkcs12_pbe_alg(&pbe_alg_oid, &md_alg, &cipher_alg) == 0) { | 
					
						
							|  |  |  |         if ((ret = mbedtls_pkcs12_pbe(&pbe_params, MBEDTLS_PKCS12_PBE_DECRYPT, | 
					
						
							|  |  |  |                                       cipher_alg, md_alg, | 
					
						
							|  |  |  |                                       pwd, pwdlen, p, len, buf)) != 0) { | 
					
						
							|  |  |  |             if (ret == MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH) { | 
					
						
							|  |  |  |                 return MBEDTLS_ERR_PK_PASSWORD_MISMATCH; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return ret; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         decrypted = 1; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } else if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid) == 0) { | 
					
						
							|  |  |  |         if ((ret = mbedtls_pkcs12_pbe_sha1_rc4_128(&pbe_params, | 
					
						
							|  |  |  |                                                    MBEDTLS_PKCS12_PBE_DECRYPT, | 
					
						
							|  |  |  |                                                    pwd, pwdlen, | 
					
						
							|  |  |  |                                                    p, len, buf)) != 0) { | 
					
						
							|  |  |  |             return ret; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Best guess for password mismatch when using RC4. If first tag is
 | 
					
						
							|  |  |  |         // not MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE
 | 
					
						
							|  |  |  |         //
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         if (*buf != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) { | 
					
						
							|  |  |  |             return MBEDTLS_ERR_PK_PASSWORD_MISMATCH; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         decrypted = 1; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } else | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | #endif /* MBEDTLS_PKCS12_C */
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_PKCS5_C)
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS5_PBES2, &pbe_alg_oid) == 0) { | 
					
						
							|  |  |  |         if ((ret = mbedtls_pkcs5_pbes2(&pbe_params, MBEDTLS_PKCS5_DECRYPT, pwd, pwdlen, | 
					
						
							|  |  |  |                                        p, len, buf)) != 0) { | 
					
						
							|  |  |  |             if (ret == MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH) { | 
					
						
							|  |  |  |                 return MBEDTLS_ERR_PK_PASSWORD_MISMATCH; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											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
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         decrypted = 1; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } else | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | #endif /* MBEDTLS_PKCS5_C */
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         ((void) pwd); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (decrypted == 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     return pk_parse_key_pkcs8_unencrypted_der(pk, buf, len); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | } | 
					
						
							|  |  |  | #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Parse a private key | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | int mbedtls_pk_parse_key(mbedtls_pk_context *pk, | 
					
						
							|  |  |  |                          const unsigned char *key, size_t keylen, | 
					
						
							|  |  |  |                          const unsigned char *pwd, size_t pwdlen) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-12-21 12:54:05 +01:00
										 |  |  |     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     const mbedtls_pk_info_t *pk_info; | 
					
						
							|  |  |  | #if defined(MBEDTLS_PEM_PARSE_C)
 | 
					
						
							|  |  |  |     size_t len; | 
					
						
							|  |  |  |     mbedtls_pem_context pem; | 
					
						
							| 
									
										
										
										
											2019-02-16 17:19:46 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     PK_VALIDATE_RET(pk != NULL); | 
					
						
							|  |  |  |     if (keylen == 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     PK_VALIDATE_RET(key != NULL); | 
					
						
							| 
									
										
										
										
											2019-02-16 17:19:46 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_PEM_PARSE_C)
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_pem_init(&pem); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_RSA_C)
 | 
					
						
							|  |  |  |     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (key[keylen - 1] != '\0') { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         ret = mbedtls_pem_read_buffer(&pem, | 
					
						
							|  |  |  |                                       "-----BEGIN RSA PRIVATE KEY-----", | 
					
						
							|  |  |  |                                       "-----END RSA PRIVATE KEY-----", | 
					
						
							|  |  |  |                                       key, pwd, pwdlen, &len); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (ret == 0) { | 
					
						
							|  |  |  |         pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA); | 
					
						
							|  |  |  |         if ((ret = mbedtls_pk_setup(pk, pk_info)) != 0 || | 
					
						
							|  |  |  |             (ret = pk_parse_key_pkcs1_der(mbedtls_pk_rsa(*pk), | 
					
						
							|  |  |  |                                           pem.buf, pem.buflen)) != 0) { | 
					
						
							|  |  |  |             mbedtls_pk_free(pk); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         mbedtls_pem_free(&pem); | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  |     } else if (ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_PASSWORD_MISMATCH; | 
					
						
							|  |  |  |     } else if (ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_PASSWORD_REQUIRED; | 
					
						
							|  |  |  |     } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { | 
					
						
							|  |  |  |         return ret; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | #endif /* MBEDTLS_RSA_C */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_ECP_C)
 | 
					
						
							|  |  |  |     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (key[keylen - 1] != '\0') { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         ret = mbedtls_pem_read_buffer(&pem, | 
					
						
							|  |  |  |                                       "-----BEGIN EC PRIVATE KEY-----", | 
					
						
							|  |  |  |                                       "-----END EC PRIVATE KEY-----", | 
					
						
							|  |  |  |                                       key, pwd, pwdlen, &len); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (ret == 0) { | 
					
						
							|  |  |  |         pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         if ((ret = mbedtls_pk_setup(pk, pk_info)) != 0 || | 
					
						
							|  |  |  |             (ret = pk_parse_key_sec1_der(mbedtls_pk_ec(*pk), | 
					
						
							|  |  |  |                                          pem.buf, pem.buflen)) != 0) { | 
					
						
							|  |  |  |             mbedtls_pk_free(pk); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         mbedtls_pem_free(&pem); | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  |     } else if (ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_PASSWORD_MISMATCH; | 
					
						
							|  |  |  |     } else if (ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_PASSWORD_REQUIRED; | 
					
						
							|  |  |  |     } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { | 
					
						
							|  |  |  |         return ret; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | #endif /* MBEDTLS_ECP_C */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (key[keylen - 1] != '\0') { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         ret = mbedtls_pem_read_buffer(&pem, | 
					
						
							|  |  |  |                                       "-----BEGIN PRIVATE KEY-----", | 
					
						
							|  |  |  |                                       "-----END PRIVATE KEY-----", | 
					
						
							|  |  |  |                                       key, NULL, 0, &len); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (ret == 0) { | 
					
						
							|  |  |  |         if ((ret = pk_parse_key_pkcs8_unencrypted_der(pk, | 
					
						
							|  |  |  |                                                       pem.buf, pem.buflen)) != 0) { | 
					
						
							|  |  |  |             mbedtls_pk_free(pk); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         mbedtls_pem_free(&pem); | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  |     } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { | 
					
						
							|  |  |  |         return ret; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
 | 
					
						
							|  |  |  |     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (key[keylen - 1] != '\0') { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         ret = mbedtls_pem_read_buffer(&pem, | 
					
						
							|  |  |  |                                       "-----BEGIN ENCRYPTED PRIVATE KEY-----", | 
					
						
							|  |  |  |                                       "-----END ENCRYPTED PRIVATE KEY-----", | 
					
						
							|  |  |  |                                       key, NULL, 0, &len); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (ret == 0) { | 
					
						
							|  |  |  |         if ((ret = pk_parse_key_pkcs8_encrypted_der(pk, | 
					
						
							|  |  |  |                                                     pem.buf, pem.buflen, | 
					
						
							|  |  |  |                                                     pwd, pwdlen)) != 0) { | 
					
						
							|  |  |  |             mbedtls_pk_free(pk); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         mbedtls_pem_free(&pem); | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  |     } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { | 
					
						
							|  |  |  |         return ret; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     ((void) pwd); | 
					
						
							|  |  |  |     ((void) pwdlen); | 
					
						
							|  |  |  | #endif /* MBEDTLS_PEM_PARSE_C */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * At this point we only know it's not a PEM formatted key. Could be any | 
					
						
							|  |  |  |      * of the known DER encoded private key formats | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * We try the different DER format parsers to see if one passes without | 
					
						
							|  |  |  |      * error | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  | #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         unsigned char *key_copy; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         if ((key_copy = mbedtls_calloc(1, keylen)) == NULL) { | 
					
						
							|  |  |  |             return MBEDTLS_ERR_PK_ALLOC_FAILED; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         memcpy(key_copy, key, keylen); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         ret = pk_parse_key_pkcs8_encrypted_der(pk, key_copy, keylen, | 
					
						
							|  |  |  |                                                pwd, pwdlen); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         mbedtls_platform_zeroize(key_copy, keylen); | 
					
						
							|  |  |  |         mbedtls_free(key_copy); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (ret == 0) { | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_pk_free(pk); | 
					
						
							|  |  |  |     mbedtls_pk_init(pk); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (ret == MBEDTLS_ERR_PK_PASSWORD_MISMATCH) { | 
					
						
							|  |  |  |         return ret; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     ret = pk_parse_key_pkcs8_unencrypted_der(pk, key, keylen); | 
					
						
							|  |  |  |     if (ret == 0) { | 
					
						
							|  |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2021-12-20 12:46:03 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_pk_free(pk); | 
					
						
							|  |  |  |     mbedtls_pk_init(pk); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_RSA_C)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA); | 
					
						
							|  |  |  |     if (mbedtls_pk_setup(pk, pk_info) == 0 && | 
					
						
							|  |  |  |         pk_parse_key_pkcs1_der(mbedtls_pk_rsa(*pk), key, keylen) == 0) { | 
					
						
							|  |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_pk_free(pk); | 
					
						
							|  |  |  |     mbedtls_pk_init(pk); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | #endif /* MBEDTLS_RSA_C */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_ECP_C)
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY); | 
					
						
							|  |  |  |     if (mbedtls_pk_setup(pk, pk_info) == 0 && | 
					
						
							|  |  |  |         pk_parse_key_sec1_der(mbedtls_pk_ec(*pk), | 
					
						
							|  |  |  |                               key, keylen) == 0) { | 
					
						
							|  |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_pk_free(pk); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | #endif /* MBEDTLS_ECP_C */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-16 17:19:46 +01:00
										 |  |  |     /* If MBEDTLS_RSA_C is defined but MBEDTLS_ECP_C isn't,
 | 
					
						
							|  |  |  |      * it is ok to leave the PK context initialized but not | 
					
						
							|  |  |  |      * freed: It is the caller's responsibility to call pk_init() | 
					
						
							|  |  |  |      * before calling this function, and to call pk_free() | 
					
						
							|  |  |  |      * when it fails. If MBEDTLS_ECP_C is defined but MBEDTLS_RSA_C | 
					
						
							|  |  |  |      * isn't, this leads to mbedtls_pk_free() being called | 
					
						
							|  |  |  |      * twice, once here and once by the caller, but this is | 
					
						
							|  |  |  |      * also ok and in line with the mbedtls_pk_free() calls | 
					
						
							|  |  |  |      * on failed PEM parsing attempts. */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Parse a public key | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  | int mbedtls_pk_parse_public_key(mbedtls_pk_context *ctx, | 
					
						
							|  |  |  |                                 const unsigned char *key, size_t keylen) | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-12-21 12:54:05 +01:00
										 |  |  |     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     unsigned char *p; | 
					
						
							| 
									
										
										
										
											2018-03-28 17:26:33 +02:00
										 |  |  | #if defined(MBEDTLS_RSA_C)
 | 
					
						
							|  |  |  |     const mbedtls_pk_info_t *pk_info; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | #if defined(MBEDTLS_PEM_PARSE_C)
 | 
					
						
							|  |  |  |     size_t len; | 
					
						
							|  |  |  |     mbedtls_pem_context pem; | 
					
						
							| 
									
										
										
										
											2019-02-16 17:19:46 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     PK_VALIDATE_RET(ctx != NULL); | 
					
						
							|  |  |  |     if (keylen == 0) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     PK_VALIDATE_RET(key != NULL || keylen == 0); | 
					
						
							| 
									
										
										
										
											2019-02-16 17:19:46 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_PEM_PARSE_C)
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_pem_init(&pem); | 
					
						
							| 
									
										
										
										
											2018-03-28 17:26:33 +02:00
										 |  |  | #if defined(MBEDTLS_RSA_C)
 | 
					
						
							|  |  |  |     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (key[keylen - 1] != '\0') { | 
					
						
							| 
									
										
										
										
											2018-03-28 17:26:33 +02:00
										 |  |  |         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         ret = mbedtls_pem_read_buffer(&pem, | 
					
						
							|  |  |  |                                       "-----BEGIN RSA PUBLIC KEY-----", | 
					
						
							|  |  |  |                                       "-----END RSA PUBLIC KEY-----", | 
					
						
							|  |  |  |                                       key, NULL, 0, &len); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-03-28 17:26:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (ret == 0) { | 
					
						
							| 
									
										
										
										
											2018-03-28 17:26:33 +02:00
										 |  |  |         p = pem.buf; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         if ((pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)) == NULL) { | 
					
						
							|  |  |  |             mbedtls_pem_free(&pem); | 
					
						
							|  |  |  |             return MBEDTLS_ERR_PK_UNKNOWN_PK_ALG; | 
					
						
							| 
									
										
										
										
											2022-07-18 14:48:00 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-28 17:26:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         if ((ret = mbedtls_pk_setup(ctx, pk_info)) != 0) { | 
					
						
							|  |  |  |             mbedtls_pem_free(&pem); | 
					
						
							|  |  |  |             return ret; | 
					
						
							| 
									
										
										
										
											2022-07-18 14:48:00 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-28 17:26:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         if ((ret = pk_get_rsapubkey(&p, p + pem.buflen, mbedtls_pk_rsa(*ctx))) != 0) { | 
					
						
							|  |  |  |             mbedtls_pk_free(ctx); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-03-28 17:26:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         mbedtls_pem_free(&pem); | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  |     } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { | 
					
						
							|  |  |  |         mbedtls_pem_free(&pem); | 
					
						
							|  |  |  |         return ret; | 
					
						
							| 
									
										
										
										
											2018-03-28 17:26:33 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | #endif /* MBEDTLS_RSA_C */
 | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (key[keylen - 1] != '\0') { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         ret = mbedtls_pem_read_buffer(&pem, | 
					
						
							|  |  |  |                                       "-----BEGIN PUBLIC KEY-----", | 
					
						
							|  |  |  |                                       "-----END PUBLIC KEY-----", | 
					
						
							|  |  |  |                                       key, NULL, 0, &len); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if (ret == 0) { | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |         /*
 | 
					
						
							|  |  |  |          * Was PEM encoded | 
					
						
							|  |  |  |          */ | 
					
						
							| 
									
										
										
										
											2018-03-28 17:26:33 +02:00
										 |  |  |         p = pem.buf; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |         ret = mbedtls_pk_parse_subpubkey(&p,  p + pem.buflen, ctx); | 
					
						
							|  |  |  |         mbedtls_pem_free(&pem); | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  |     } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) { | 
					
						
							|  |  |  |         mbedtls_pem_free(&pem); | 
					
						
							|  |  |  |         return ret; | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_pem_free(&pem); | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  | #endif /* MBEDTLS_PEM_PARSE_C */
 | 
					
						
							| 
									
										
										
										
											2018-03-28 17:26:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if defined(MBEDTLS_RSA_C)
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)) == NULL) { | 
					
						
							|  |  |  |         return MBEDTLS_ERR_PK_UNKNOWN_PK_ALG; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-03-28 17:26:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     if ((ret = mbedtls_pk_setup(ctx, pk_info)) != 0) { | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-03-28 17:26:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     p = (unsigned char *) key; | 
					
						
							|  |  |  |     ret = pk_get_rsapubkey(&p, p + keylen, mbedtls_pk_rsa(*ctx)); | 
					
						
							|  |  |  |     if (ret == 0) { | 
					
						
							|  |  |  |         return ret; | 
					
						
							| 
									
										
										
										
											2018-03-28 17:26:33 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     mbedtls_pk_free(ctx); | 
					
						
							|  |  |  |     if (ret != (MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, | 
					
						
							|  |  |  |                                   MBEDTLS_ERR_ASN1_UNEXPECTED_TAG))) { | 
					
						
							|  |  |  |         return ret; | 
					
						
							| 
									
										
										
										
											2018-03-28 17:26:33 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | #endif /* MBEDTLS_RSA_C */
 | 
					
						
							| 
									
										
										
										
											2018-02-08 19:04:43 +01:00
										 |  |  |     p = (unsigned char *) key; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 10:38:24 +02:00
										 |  |  |     ret = mbedtls_pk_parse_subpubkey(&p, p + keylen, ctx); | 
					
						
							| 
									
										
										
										
											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_PK_PARSE_C */
 |