blob: 377c106d8c1260f3151ae8af563f13ab50b7f6a8 [file] [log] [blame]
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001/*
Manuel Pégourié-Gonnard1c082f32014-06-12 22:34:55 +02002 * X.509 common functions for parsing and verification
Paul Bakker7c6b2c32013-09-16 13:49:26 +02003 *
Bence Szépkúti44bfbe32020-08-19 16:54:51 +02004 * Copyright The Mbed TLS Contributors
Bence Szépkúti4e9f7122020-06-05 13:02:18 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 *
7 * This file is provided under the Apache License 2.0, or the
8 * GNU General Public License v2.0 or later.
9 *
10 * **********
11 * Apache License 2.0:
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +020012 *
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
Paul Bakker7c6b2c32013-09-16 13:49:26 +020024 *
Bence Szépkúti4e9f7122020-06-05 13:02:18 +020025 * **********
26 *
27 * **********
28 * GNU General Public License v2.0 or later:
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License along
41 * with this program; if not, write to the Free Software Foundation, Inc.,
42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43 *
44 * **********
Paul Bakker7c6b2c32013-09-16 13:49:26 +020045 */
46/*
47 * The ITU-T X.509 standard defines a certificate format for PKI.
48 *
Manuel Pégourié-Gonnard1c082f32014-06-12 22:34:55 +020049 * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
50 * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
51 * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
Paul Bakker7c6b2c32013-09-16 13:49:26 +020052 *
53 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
54 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
55 */
56
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020057#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000058#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020059#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020060#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020061#endif
Paul Bakker7c6b2c32013-09-16 13:49:26 +020062
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020063#if defined(MBEDTLS_X509_USE_C)
Paul Bakker7c6b2c32013-09-16 13:49:26 +020064
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000065#include "mbedtls/x509.h"
66#include "mbedtls/asn1.h"
67#include "mbedtls/oid.h"
Rich Evans00ab4702015-02-06 13:43:58 +000068
Rich Evans36796df2015-02-12 18:27:14 +000069#include <stdio.h>
Rich Evans00ab4702015-02-06 13:43:58 +000070#include <string.h>
71
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020072#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000073#include "mbedtls/pem.h"
Paul Bakker7c6b2c32013-09-16 13:49:26 +020074#endif
75
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020076#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000077#include "mbedtls/platform.h"
Paul Bakker7c6b2c32013-09-16 13:49:26 +020078#else
Rich Evans00ab4702015-02-06 13:43:58 +000079#include <stdio.h>
80#include <stdlib.h>
SimonBd5800b72016-04-26 07:43:27 +010081#define mbedtls_free free
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +020082#define mbedtls_calloc calloc
SimonBd5800b72016-04-26 07:43:27 +010083#define mbedtls_printf printf
84#define mbedtls_snprintf snprintf
Paul Bakker7c6b2c32013-09-16 13:49:26 +020085#endif
86
Simon Butcherb5b6af22016-07-13 14:46:18 +010087
88#if defined(MBEDTLS_HAVE_TIME)
89#include "mbedtls/platform_time.h"
90#endif
91
Paul Bakkerfa6a6202013-10-28 18:48:30 +010092#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
Paul Bakker7c6b2c32013-09-16 13:49:26 +020093#include <windows.h>
94#else
95#include <time.h>
96#endif
97
Rich Evans7d5a55a2015-02-13 11:48:02 +000098#define CHECK(code) if( ( ret = code ) != 0 ){ return( ret ); }
Andres AG4b76aec2016-09-23 13:16:02 +010099#define CHECK_RANGE(min, max, val) if( val < min || val > max ){ return( ret ); }
Rich Evans7d5a55a2015-02-13 11:48:02 +0000100
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200101/*
102 * CertificateSerialNumber ::= INTEGER
103 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200104int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end,
105 mbedtls_x509_buf *serial )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200106{
107 int ret;
108
109 if( ( end - *p ) < 1 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200110 return( MBEDTLS_ERR_X509_INVALID_SERIAL +
111 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200112
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200113 if( **p != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_PRIMITIVE | 2 ) &&
114 **p != MBEDTLS_ASN1_INTEGER )
115 return( MBEDTLS_ERR_X509_INVALID_SERIAL +
116 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200117
118 serial->tag = *(*p)++;
119
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200120 if( ( ret = mbedtls_asn1_get_len( p, end, &serial->len ) ) != 0 )
121 return( MBEDTLS_ERR_X509_INVALID_SERIAL + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200122
123 serial->p = *p;
124 *p += serial->len;
125
126 return( 0 );
127}
128
129/* Get an algorithm identifier without parameters (eg for signatures)
130 *
131 * AlgorithmIdentifier ::= SEQUENCE {
132 * algorithm OBJECT IDENTIFIER,
133 * parameters ANY DEFINED BY algorithm OPTIONAL }
134 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200135int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end,
136 mbedtls_x509_buf *alg )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200137{
138 int ret;
139
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200140 if( ( ret = mbedtls_asn1_get_alg_null( p, end, alg ) ) != 0 )
141 return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200142
143 return( 0 );
144}
145
146/*
Antonin Décimo8fd91562019-01-23 15:24:37 +0100147 * Parse an algorithm identifier with (optional) parameters
Manuel Pégourié-Gonnard59a75d52014-01-22 10:12:57 +0100148 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200149int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end,
150 mbedtls_x509_buf *alg, mbedtls_x509_buf *params )
Manuel Pégourié-Gonnard59a75d52014-01-22 10:12:57 +0100151{
152 int ret;
153
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200154 if( ( ret = mbedtls_asn1_get_alg( p, end, alg, params ) ) != 0 )
155 return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
Manuel Pégourié-Gonnard59a75d52014-01-22 10:12:57 +0100156
157 return( 0 );
158}
159
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200160#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
Manuel Pégourié-Gonnard59a75d52014-01-22 10:12:57 +0100161/*
Manuel Pégourié-Gonnarde76b7502014-01-23 19:15:29 +0100162 * HashAlgorithm ::= AlgorithmIdentifier
163 *
164 * AlgorithmIdentifier ::= SEQUENCE {
165 * algorithm OBJECT IDENTIFIER,
166 * parameters ANY DEFINED BY algorithm OPTIONAL }
167 *
168 * For HashAlgorithm, parameters MUST be NULL or absent.
169 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200170static int x509_get_hash_alg( const mbedtls_x509_buf *alg, mbedtls_md_type_t *md_alg )
Manuel Pégourié-Gonnarde76b7502014-01-23 19:15:29 +0100171{
172 int ret;
173 unsigned char *p;
174 const unsigned char *end;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200175 mbedtls_x509_buf md_oid;
Manuel Pégourié-Gonnarde76b7502014-01-23 19:15:29 +0100176 size_t len;
177
178 /* Make sure we got a SEQUENCE and setup bounds */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200179 if( alg->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
180 return( MBEDTLS_ERR_X509_INVALID_ALG +
181 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
Manuel Pégourié-Gonnarde76b7502014-01-23 19:15:29 +0100182
183 p = (unsigned char *) alg->p;
184 end = p + alg->len;
185
186 if( p >= end )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200187 return( MBEDTLS_ERR_X509_INVALID_ALG +
188 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
Manuel Pégourié-Gonnarde76b7502014-01-23 19:15:29 +0100189
190 /* Parse md_oid */
191 md_oid.tag = *p;
192
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200193 if( ( ret = mbedtls_asn1_get_tag( &p, end, &md_oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
194 return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
Manuel Pégourié-Gonnarde76b7502014-01-23 19:15:29 +0100195
196 md_oid.p = p;
197 p += md_oid.len;
198
199 /* Get md_alg from md_oid */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200200 if( ( ret = mbedtls_oid_get_md_alg( &md_oid, md_alg ) ) != 0 )
201 return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
Manuel Pégourié-Gonnarde76b7502014-01-23 19:15:29 +0100202
203 /* Make sure params is absent of NULL */
204 if( p == end )
205 return( 0 );
206
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200207 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_NULL ) ) != 0 || len != 0 )
208 return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
Manuel Pégourié-Gonnarde76b7502014-01-23 19:15:29 +0100209
210 if( p != end )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200211 return( MBEDTLS_ERR_X509_INVALID_ALG +
212 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
Manuel Pégourié-Gonnarde76b7502014-01-23 19:15:29 +0100213
214 return( 0 );
215}
216
217/*
Manuel Pégourié-Gonnardf346bab2014-01-23 16:24:44 +0100218 * RSASSA-PSS-params ::= SEQUENCE {
219 * hashAlgorithm [0] HashAlgorithm DEFAULT sha1Identifier,
220 * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier,
221 * saltLength [2] INTEGER DEFAULT 20,
222 * trailerField [3] INTEGER DEFAULT 1 }
223 * -- Note that the tags in this Sequence are explicit.
Manuel Pégourié-Gonnard78117d52014-05-31 17:08:16 +0200224 *
225 * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value
226 * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other
227 * option. Enfore this at parsing time.
Manuel Pégourié-Gonnardf346bab2014-01-23 16:24:44 +0100228 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200229int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
230 mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md,
Manuel Pégourié-Gonnard78117d52014-05-31 17:08:16 +0200231 int *salt_len )
Manuel Pégourié-Gonnardf346bab2014-01-23 16:24:44 +0100232{
233 int ret;
234 unsigned char *p;
Manuel Pégourié-Gonnard9c9cf5b2014-01-24 14:15:20 +0100235 const unsigned char *end, *end2;
Manuel Pégourié-Gonnardf346bab2014-01-23 16:24:44 +0100236 size_t len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200237 mbedtls_x509_buf alg_id, alg_params;
Manuel Pégourié-Gonnardf346bab2014-01-23 16:24:44 +0100238
239 /* First set everything to defaults */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200240 *md_alg = MBEDTLS_MD_SHA1;
241 *mgf_md = MBEDTLS_MD_SHA1;
Manuel Pégourié-Gonnardf346bab2014-01-23 16:24:44 +0100242 *salt_len = 20;
Manuel Pégourié-Gonnardf346bab2014-01-23 16:24:44 +0100243
244 /* Make sure params is a SEQUENCE and setup bounds */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200245 if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
246 return( MBEDTLS_ERR_X509_INVALID_ALG +
247 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
Manuel Pégourié-Gonnardf346bab2014-01-23 16:24:44 +0100248
249 p = (unsigned char *) params->p;
250 end = p + params->len;
251
252 if( p == end )
253 return( 0 );
254
Manuel Pégourié-Gonnard9c9cf5b2014-01-24 14:15:20 +0100255 /*
256 * HashAlgorithm
257 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200258 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
259 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 )
Manuel Pégourié-Gonnardf346bab2014-01-23 16:24:44 +0100260 {
Manuel Pégourié-Gonnard9c9cf5b2014-01-24 14:15:20 +0100261 end2 = p + len;
262
Manuel Pégourié-Gonnarde76b7502014-01-23 19:15:29 +0100263 /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200264 if( ( ret = mbedtls_x509_get_alg_null( &p, end2, &alg_id ) ) != 0 )
Manuel Pégourié-Gonnarde76b7502014-01-23 19:15:29 +0100265 return( ret );
266
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200267 if( ( ret = mbedtls_oid_get_md_alg( &alg_id, md_alg ) ) != 0 )
268 return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
Manuel Pégourié-Gonnard9c9cf5b2014-01-24 14:15:20 +0100269
270 if( p != end2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200271 return( MBEDTLS_ERR_X509_INVALID_ALG +
272 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
Manuel Pégourié-Gonnardf346bab2014-01-23 16:24:44 +0100273 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200274 else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
275 return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
Manuel Pégourié-Gonnardf346bab2014-01-23 16:24:44 +0100276
Manuel Pégourié-Gonnard9c9cf5b2014-01-24 14:15:20 +0100277 if( p == end )
278 return( 0 );
279
280 /*
281 * MaskGenAlgorithm
282 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200283 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
284 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 )
Manuel Pégourié-Gonnardf346bab2014-01-23 16:24:44 +0100285 {
Manuel Pégourié-Gonnard9c9cf5b2014-01-24 14:15:20 +0100286 end2 = p + len;
287
Manuel Pégourié-Gonnarde76b7502014-01-23 19:15:29 +0100288 /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200289 if( ( ret = mbedtls_x509_get_alg( &p, end2, &alg_id, &alg_params ) ) != 0 )
Manuel Pégourié-Gonnarde76b7502014-01-23 19:15:29 +0100290 return( ret );
291
292 /* Only MFG1 is recognised for now */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200293 if( MBEDTLS_OID_CMP( MBEDTLS_OID_MGF1, &alg_id ) != 0 )
294 return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE +
295 MBEDTLS_ERR_OID_NOT_FOUND );
Manuel Pégourié-Gonnarde76b7502014-01-23 19:15:29 +0100296
297 /* Parse HashAlgorithm */
298 if( ( ret = x509_get_hash_alg( &alg_params, mgf_md ) ) != 0 )
299 return( ret );
Manuel Pégourié-Gonnard9c9cf5b2014-01-24 14:15:20 +0100300
301 if( p != end2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200302 return( MBEDTLS_ERR_X509_INVALID_ALG +
303 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
Manuel Pégourié-Gonnardf346bab2014-01-23 16:24:44 +0100304 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200305 else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
306 return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
Manuel Pégourié-Gonnardf346bab2014-01-23 16:24:44 +0100307
308 if( p == end )
309 return( 0 );
310
Manuel Pégourié-Gonnard9c9cf5b2014-01-24 14:15:20 +0100311 /*
312 * salt_len
313 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200314 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
315 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 2 ) ) == 0 )
Manuel Pégourié-Gonnardf346bab2014-01-23 16:24:44 +0100316 {
Manuel Pégourié-Gonnard9c9cf5b2014-01-24 14:15:20 +0100317 end2 = p + len;
318
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200319 if( ( ret = mbedtls_asn1_get_int( &p, end2, salt_len ) ) != 0 )
320 return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
Manuel Pégourié-Gonnard9c9cf5b2014-01-24 14:15:20 +0100321
322 if( p != end2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200323 return( MBEDTLS_ERR_X509_INVALID_ALG +
324 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
Manuel Pégourié-Gonnardf346bab2014-01-23 16:24:44 +0100325 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200326 else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
327 return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
Manuel Pégourié-Gonnardf346bab2014-01-23 16:24:44 +0100328
329 if( p == end )
330 return( 0 );
331
Manuel Pégourié-Gonnard9c9cf5b2014-01-24 14:15:20 +0100332 /*
Manuel Pégourié-Gonnard78117d52014-05-31 17:08:16 +0200333 * trailer_field (if present, must be 1)
Manuel Pégourié-Gonnard9c9cf5b2014-01-24 14:15:20 +0100334 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200335 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
336 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 3 ) ) == 0 )
Manuel Pégourié-Gonnardf346bab2014-01-23 16:24:44 +0100337 {
Manuel Pégourié-Gonnard78117d52014-05-31 17:08:16 +0200338 int trailer_field;
339
Manuel Pégourié-Gonnard9c9cf5b2014-01-24 14:15:20 +0100340 end2 = p + len;
341
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200342 if( ( ret = mbedtls_asn1_get_int( &p, end2, &trailer_field ) ) != 0 )
343 return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
Manuel Pégourié-Gonnard9c9cf5b2014-01-24 14:15:20 +0100344
345 if( p != end2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200346 return( MBEDTLS_ERR_X509_INVALID_ALG +
347 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
Manuel Pégourié-Gonnard78117d52014-05-31 17:08:16 +0200348
349 if( trailer_field != 1 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200350 return( MBEDTLS_ERR_X509_INVALID_ALG );
Manuel Pégourié-Gonnardf346bab2014-01-23 16:24:44 +0100351 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200352 else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
353 return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
Manuel Pégourié-Gonnardf346bab2014-01-23 16:24:44 +0100354
355 if( p != end )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200356 return( MBEDTLS_ERR_X509_INVALID_ALG +
357 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
Manuel Pégourié-Gonnardf346bab2014-01-23 16:24:44 +0100358
359 return( 0 );
360}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200361#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
Manuel Pégourié-Gonnardf346bab2014-01-23 16:24:44 +0100362
363/*
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200364 * AttributeTypeAndValue ::= SEQUENCE {
365 * type AttributeType,
366 * value AttributeValue }
367 *
368 * AttributeType ::= OBJECT IDENTIFIER
369 *
370 * AttributeValue ::= ANY DEFINED BY AttributeType
371 */
372static int x509_get_attr_type_value( unsigned char **p,
373 const unsigned char *end,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200374 mbedtls_x509_name *cur )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200375{
376 int ret;
377 size_t len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200378 mbedtls_x509_buf *oid;
379 mbedtls_x509_buf *val;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200380
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200381 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
382 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
383 return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200384
Hanno Becker1de13db2019-02-12 17:22:36 +0000385 end = *p + len;
386
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200387 if( ( end - *p ) < 1 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200388 return( MBEDTLS_ERR_X509_INVALID_NAME +
389 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200390
391 oid = &cur->oid;
392 oid->tag = **p;
393
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200394 if( ( ret = mbedtls_asn1_get_tag( p, end, &oid->len, MBEDTLS_ASN1_OID ) ) != 0 )
395 return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200396
397 oid->p = *p;
398 *p += oid->len;
399
400 if( ( end - *p ) < 1 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200401 return( MBEDTLS_ERR_X509_INVALID_NAME +
402 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200403
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200404 if( **p != MBEDTLS_ASN1_BMP_STRING && **p != MBEDTLS_ASN1_UTF8_STRING &&
405 **p != MBEDTLS_ASN1_T61_STRING && **p != MBEDTLS_ASN1_PRINTABLE_STRING &&
406 **p != MBEDTLS_ASN1_IA5_STRING && **p != MBEDTLS_ASN1_UNIVERSAL_STRING &&
407 **p != MBEDTLS_ASN1_BIT_STRING )
408 return( MBEDTLS_ERR_X509_INVALID_NAME +
409 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200410
411 val = &cur->val;
412 val->tag = *(*p)++;
413
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200414 if( ( ret = mbedtls_asn1_get_len( p, end, &val->len ) ) != 0 )
415 return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200416
417 val->p = *p;
418 *p += val->len;
419
Hanno Becker1de13db2019-02-12 17:22:36 +0000420 if( *p != end )
421 {
422 return( MBEDTLS_ERR_X509_INVALID_NAME +
423 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
424 }
425
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200426 cur->next = NULL;
427
428 return( 0 );
429}
430
431/*
Manuel Pégourié-Gonnard555fbf82015-02-04 17:11:55 +0000432 * Name ::= CHOICE { -- only one possibility for now --
433 * rdnSequence RDNSequence }
434 *
435 * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
436 *
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200437 * RelativeDistinguishedName ::=
438 * SET OF AttributeTypeAndValue
439 *
440 * AttributeTypeAndValue ::= SEQUENCE {
441 * type AttributeType,
442 * value AttributeValue }
443 *
444 * AttributeType ::= OBJECT IDENTIFIER
445 *
446 * AttributeValue ::= ANY DEFINED BY AttributeType
Manuel Pégourié-Gonnard5d861852014-10-17 12:41:41 +0200447 *
Manuel Pégourié-Gonnard555fbf82015-02-04 17:11:55 +0000448 * The data structure is optimized for the common case where each RDN has only
449 * one element, which is represented as a list of AttributeTypeAndValue.
450 * For the general case we still use a flat list, but we mark elements of the
451 * same set so that they are "merged" together in the functions that consume
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200452 * this list, eg mbedtls_x509_dn_gets().
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200453 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200454int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end,
455 mbedtls_x509_name *cur )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200456{
457 int ret;
Manuel Pégourié-Gonnard5d861852014-10-17 12:41:41 +0200458 size_t set_len;
459 const unsigned char *end_set;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200460
Manuel Pégourié-Gonnardd6814432014-11-12 01:25:31 +0100461 /* don't use recursion, we'd risk stack overflow if not optimized */
462 while( 1 )
463 {
464 /*
Manuel Pégourié-Gonnard555fbf82015-02-04 17:11:55 +0000465 * parse SET
Manuel Pégourié-Gonnardd6814432014-11-12 01:25:31 +0100466 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200467 if( ( ret = mbedtls_asn1_get_tag( p, end, &set_len,
468 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) ) != 0 )
469 return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200470
Manuel Pégourié-Gonnardd6814432014-11-12 01:25:31 +0100471 end_set = *p + set_len;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200472
Manuel Pégourié-Gonnard555fbf82015-02-04 17:11:55 +0000473 while( 1 )
474 {
475 if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 )
476 return( ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200477
Manuel Pégourié-Gonnard555fbf82015-02-04 17:11:55 +0000478 if( *p == end_set )
479 break;
480
Manuel Pégourié-Gonnardeecb43c2015-05-12 12:56:41 +0200481 /* Mark this item as being no the only one in a set */
Manuel Pégourié-Gonnard555fbf82015-02-04 17:11:55 +0000482 cur->next_merged = 1;
483
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200484 cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) );
Manuel Pégourié-Gonnard555fbf82015-02-04 17:11:55 +0000485
486 if( cur->next == NULL )
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +0200487 return( MBEDTLS_ERR_X509_ALLOC_FAILED );
Manuel Pégourié-Gonnard555fbf82015-02-04 17:11:55 +0000488
Manuel Pégourié-Gonnard555fbf82015-02-04 17:11:55 +0000489 cur = cur->next;
490 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200491
Manuel Pégourié-Gonnardd6814432014-11-12 01:25:31 +0100492 /*
493 * continue until end of SEQUENCE is reached
494 */
495 if( *p == end )
496 return( 0 );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200497
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200498 cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200499
Manuel Pégourié-Gonnardd6814432014-11-12 01:25:31 +0100500 if( cur->next == NULL )
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +0200501 return( MBEDTLS_ERR_X509_ALLOC_FAILED );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200502
Manuel Pégourié-Gonnardd6814432014-11-12 01:25:31 +0100503 cur = cur->next;
504 }
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200505}
506
Janos Follath87c98072017-02-03 12:36:59 +0000507static int x509_parse_int( unsigned char **p, size_t n, int *res )
508{
Rich Evans7d5a55a2015-02-13 11:48:02 +0000509 *res = 0;
Janos Follath87c98072017-02-03 12:36:59 +0000510
511 for( ; n > 0; --n )
512 {
513 if( ( **p < '0') || ( **p > '9' ) )
514 return ( MBEDTLS_ERR_X509_INVALID_DATE );
515
Rich Evans7d5a55a2015-02-13 11:48:02 +0000516 *res *= 10;
Janos Follath87c98072017-02-03 12:36:59 +0000517 *res += ( *(*p)++ - '0' );
Rich Evans7d5a55a2015-02-13 11:48:02 +0000518 }
Janos Follath87c98072017-02-03 12:36:59 +0000519
520 return( 0 );
Rich Evans7d5a55a2015-02-13 11:48:02 +0000521}
522
Andres Amaya Garcia735b37e2016-11-21 15:38:02 +0000523static int x509_date_is_valid(const mbedtls_x509_time *t )
Andres AG4b76aec2016-09-23 13:16:02 +0100524{
525 int ret = MBEDTLS_ERR_X509_INVALID_DATE;
Andres Amaya Garcia735b37e2016-11-21 15:38:02 +0000526 int month_len;
Andres AG4b76aec2016-09-23 13:16:02 +0100527
Hanno Becker61937d42017-04-26 15:01:23 +0100528 CHECK_RANGE( 0, 9999, t->year );
529 CHECK_RANGE( 0, 23, t->hour );
530 CHECK_RANGE( 0, 59, t->min );
531 CHECK_RANGE( 0, 59, t->sec );
Andres AG4b76aec2016-09-23 13:16:02 +0100532
Hanno Becker61937d42017-04-26 15:01:23 +0100533 switch( t->mon )
Andres AG4b76aec2016-09-23 13:16:02 +0100534 {
535 case 1: case 3: case 5: case 7: case 8: case 10: case 12:
Andres Amaya Garcia735b37e2016-11-21 15:38:02 +0000536 month_len = 31;
Andres AG4b76aec2016-09-23 13:16:02 +0100537 break;
538 case 4: case 6: case 9: case 11:
Andres Amaya Garcia735b37e2016-11-21 15:38:02 +0000539 month_len = 30;
Andres AG4b76aec2016-09-23 13:16:02 +0100540 break;
541 case 2:
Andres Amaya Garcia735b37e2016-11-21 15:38:02 +0000542 if( ( !( t->year % 4 ) && t->year % 100 ) ||
543 !( t->year % 400 ) )
544 month_len = 29;
545 else
546 month_len = 28;
Andres AG4b76aec2016-09-23 13:16:02 +0100547 break;
548 default:
549 return( ret );
550 }
Andres Amaya Garcia735b37e2016-11-21 15:38:02 +0000551 CHECK_RANGE( 1, month_len, t->day );
Andres AG4b76aec2016-09-23 13:16:02 +0100552
553 return( 0 );
554}
555
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200556/*
Janos Follath87c98072017-02-03 12:36:59 +0000557 * Parse an ASN1_UTC_TIME (yearlen=2) or ASN1_GENERALIZED_TIME (yearlen=4)
558 * field.
559 */
560static int x509_parse_time( unsigned char **p, size_t len, size_t yearlen,
Hanno Becker61937d42017-04-26 15:01:23 +0100561 mbedtls_x509_time *tm )
Janos Follath87c98072017-02-03 12:36:59 +0000562{
563 int ret;
564
565 /*
566 * Minimum length is 10 or 12 depending on yearlen
567 */
568 if ( len < yearlen + 8 )
569 return ( MBEDTLS_ERR_X509_INVALID_DATE );
570 len -= yearlen + 8;
571
572 /*
573 * Parse year, month, day, hour, minute
574 */
Hanno Becker61937d42017-04-26 15:01:23 +0100575 CHECK( x509_parse_int( p, yearlen, &tm->year ) );
Janos Follath87c98072017-02-03 12:36:59 +0000576 if ( 2 == yearlen )
577 {
Hanno Becker61937d42017-04-26 15:01:23 +0100578 if ( tm->year < 50 )
579 tm->year += 100;
Janos Follath87c98072017-02-03 12:36:59 +0000580
Hanno Becker61937d42017-04-26 15:01:23 +0100581 tm->year += 1900;
Janos Follath87c98072017-02-03 12:36:59 +0000582 }
583
Hanno Becker61937d42017-04-26 15:01:23 +0100584 CHECK( x509_parse_int( p, 2, &tm->mon ) );
585 CHECK( x509_parse_int( p, 2, &tm->day ) );
586 CHECK( x509_parse_int( p, 2, &tm->hour ) );
587 CHECK( x509_parse_int( p, 2, &tm->min ) );
Janos Follath87c98072017-02-03 12:36:59 +0000588
589 /*
590 * Parse seconds if present
591 */
592 if ( len >= 2 )
593 {
Hanno Becker61937d42017-04-26 15:01:23 +0100594 CHECK( x509_parse_int( p, 2, &tm->sec ) );
Janos Follath87c98072017-02-03 12:36:59 +0000595 len -= 2;
596 }
597 else
598 return ( MBEDTLS_ERR_X509_INVALID_DATE );
599
600 /*
601 * Parse trailing 'Z' if present
602 */
603 if ( 1 == len && 'Z' == **p )
604 {
605 (*p)++;
606 len--;
607 }
608
609 /*
610 * We should have parsed all characters at this point
611 */
612 if ( 0 != len )
613 return ( MBEDTLS_ERR_X509_INVALID_DATE );
614
Hanno Becker61937d42017-04-26 15:01:23 +0100615 CHECK( x509_date_is_valid( tm ) );
Janos Follath87c98072017-02-03 12:36:59 +0000616
617 return ( 0 );
618}
619
620/*
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200621 * Time ::= CHOICE {
622 * utcTime UTCTime,
623 * generalTime GeneralizedTime }
624 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200625int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end,
Hanno Becker61937d42017-04-26 15:01:23 +0100626 mbedtls_x509_time *tm )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200627{
628 int ret;
Janos Follath87c98072017-02-03 12:36:59 +0000629 size_t len, year_len;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200630 unsigned char tag;
631
632 if( ( end - *p ) < 1 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200633 return( MBEDTLS_ERR_X509_INVALID_DATE +
634 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200635
636 tag = **p;
637
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200638 if( tag == MBEDTLS_ASN1_UTC_TIME )
Janos Follath87c98072017-02-03 12:36:59 +0000639 year_len = 2;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200640 else if( tag == MBEDTLS_ASN1_GENERALIZED_TIME )
Janos Follath87c98072017-02-03 12:36:59 +0000641 year_len = 4;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200642 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200643 return( MBEDTLS_ERR_X509_INVALID_DATE +
644 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
Janos Follath87c98072017-02-03 12:36:59 +0000645
646 (*p)++;
647 ret = mbedtls_asn1_get_len( p, end, &len );
648
649 if( ret != 0 )
650 return( MBEDTLS_ERR_X509_INVALID_DATE + ret );
651
Hanno Becker61937d42017-04-26 15:01:23 +0100652 return x509_parse_time( p, len, year_len, tm );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200653}
654
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200655int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200656{
657 int ret;
658 size_t len;
Andres AG4bdbe092016-09-19 16:58:45 +0100659 int tag_type;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200660
661 if( ( end - *p ) < 1 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200662 return( MBEDTLS_ERR_X509_INVALID_SIGNATURE +
663 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200664
Andres AG4bdbe092016-09-19 16:58:45 +0100665 tag_type = **p;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200666
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200667 if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 )
668 return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200669
Andres AG4bdbe092016-09-19 16:58:45 +0100670 sig->tag = tag_type;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200671 sig->len = len;
672 sig->p = *p;
673
674 *p += len;
675
676 return( 0 );
677}
678
Manuel Pégourié-Gonnardcf975a32014-01-24 19:28:43 +0100679/*
680 * Get signature algorithm from alg OID and optional parameters
681 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200682int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params,
683 mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg,
Manuel Pégourié-Gonnardf75f2f72014-06-05 15:14:28 +0200684 void **sig_opts )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200685{
Manuel Pégourié-Gonnardcf975a32014-01-24 19:28:43 +0100686 int ret;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200687
Manuel Pégourié-Gonnardf75f2f72014-06-05 15:14:28 +0200688 if( *sig_opts != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200689 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
Manuel Pégourié-Gonnardf75f2f72014-06-05 15:14:28 +0200690
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200691 if( ( ret = mbedtls_oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 )
692 return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200693
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200694#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
695 if( *pk_alg == MBEDTLS_PK_RSASSA_PSS )
Manuel Pégourié-Gonnardcf975a32014-01-24 19:28:43 +0100696 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200697 mbedtls_pk_rsassa_pss_options *pss_opts;
Manuel Pégourié-Gonnardcf975a32014-01-24 19:28:43 +0100698
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200699 pss_opts = mbedtls_calloc( 1, sizeof( mbedtls_pk_rsassa_pss_options ) );
Manuel Pégourié-Gonnardf75f2f72014-06-05 15:14:28 +0200700 if( pss_opts == NULL )
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +0200701 return( MBEDTLS_ERR_X509_ALLOC_FAILED );
Manuel Pégourié-Gonnardf75f2f72014-06-05 15:14:28 +0200702
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200703 ret = mbedtls_x509_get_rsassa_pss_params( sig_params,
Manuel Pégourié-Gonnardf75f2f72014-06-05 15:14:28 +0200704 md_alg,
705 &pss_opts->mgf1_hash_id,
706 &pss_opts->expected_salt_len );
Manuel Pégourié-Gonnardcf975a32014-01-24 19:28:43 +0100707 if( ret != 0 )
Manuel Pégourié-Gonnardf75f2f72014-06-05 15:14:28 +0200708 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200709 mbedtls_free( pss_opts );
Manuel Pégourié-Gonnardcf975a32014-01-24 19:28:43 +0100710 return( ret );
Manuel Pégourié-Gonnardf75f2f72014-06-05 15:14:28 +0200711 }
Manuel Pégourié-Gonnardcf975a32014-01-24 19:28:43 +0100712
Manuel Pégourié-Gonnardf75f2f72014-06-05 15:14:28 +0200713 *sig_opts = (void *) pss_opts;
Manuel Pégourié-Gonnardcf975a32014-01-24 19:28:43 +0100714 }
715 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200716#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
Manuel Pégourié-Gonnardcf975a32014-01-24 19:28:43 +0100717 {
718 /* Make sure parameters are absent or NULL */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200719 if( ( sig_params->tag != MBEDTLS_ASN1_NULL && sig_params->tag != 0 ) ||
Manuel Pégourié-Gonnardcf975a32014-01-24 19:28:43 +0100720 sig_params->len != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200721 return( MBEDTLS_ERR_X509_INVALID_ALG );
Manuel Pégourié-Gonnardcf975a32014-01-24 19:28:43 +0100722 }
723
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200724 return( 0 );
725}
726
727/*
728 * X.509 Extensions (No parsing of extensions, pointer should
Brian J Murray1903fb32016-11-06 04:45:15 -0800729 * be either manually updated or extensions should be parsed!)
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200730 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200731int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end,
Hanno Becker19557c22019-02-12 11:52:10 +0000732 mbedtls_x509_buf *ext, int tag )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200733{
734 int ret;
735 size_t len;
736
Hanno Beckerc24e0192019-02-11 14:33:36 +0000737 /* Extension structure use EXPLICIT tagging. That is, the actual
738 * `Extensions` structure is wrapped by a tag-length pair using
739 * the respective context-specific tag. */
Hanno Becker19557c22019-02-12 11:52:10 +0000740 ret = mbedtls_asn1_get_tag( p, end, &ext->len,
741 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag );
742 if( ret != 0 )
743 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200744
Hanno Becker19557c22019-02-12 11:52:10 +0000745 ext->tag = MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag;
746 ext->p = *p;
747 end = *p + ext->len;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200748
749 /*
750 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200751 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200752 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
753 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
754 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200755
756 if( end != *p + len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200757 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
758 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200759
760 return( 0 );
761}
762
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200763/*
764 * Store the name in printable form into buf; no more
765 * than size characters will be written
766 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200767int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200768{
769 int ret;
770 size_t i, n;
Manuel Pégourié-Gonnard555fbf82015-02-04 17:11:55 +0000771 unsigned char c, merge = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200772 const mbedtls_x509_name *name;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200773 const char *short_name = NULL;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200774 char s[MBEDTLS_X509_MAX_DN_NAME_SIZE], *p;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200775
776 memset( s, 0, sizeof( s ) );
777
778 name = dn;
779 p = buf;
780 n = size;
781
782 while( name != NULL )
783 {
784 if( !name->oid.p )
785 {
786 name = name->next;
787 continue;
788 }
789
790 if( name != dn )
791 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200792 ret = mbedtls_snprintf( p, n, merge ? " + " : ", " );
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200793 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200794 }
795
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200796 ret = mbedtls_oid_get_attr_short_name( &name->oid, &short_name );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200797
798 if( ret == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200799 ret = mbedtls_snprintf( p, n, "%s=", short_name );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200800 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200801 ret = mbedtls_snprintf( p, n, "\?\?=" );
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200802 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200803
804 for( i = 0; i < name->val.len; i++ )
805 {
806 if( i >= sizeof( s ) - 1 )
807 break;
808
809 c = name->val.p[i];
810 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
811 s[i] = '?';
812 else s[i] = c;
813 }
814 s[i] = '\0';
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200815 ret = mbedtls_snprintf( p, n, "%s", s );
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200816 MBEDTLS_X509_SAFE_SNPRINTF;
Manuel Pégourié-Gonnard555fbf82015-02-04 17:11:55 +0000817
818 merge = name->next_merged;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200819 name = name->next;
820 }
821
822 return( (int) ( size - n ) );
823}
824
825/*
826 * Store the serial in printable form into buf; no more
827 * than size characters will be written
828 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200829int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200830{
831 int ret;
832 size_t i, n, nr;
833 char *p;
834
835 p = buf;
836 n = size;
837
838 nr = ( serial->len <= 32 )
839 ? serial->len : 28;
840
841 for( i = 0; i < nr; i++ )
842 {
843 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
844 continue;
845
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200846 ret = mbedtls_snprintf( p, n, "%02X%s",
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200847 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200848 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200849 }
850
851 if( nr != serial->len )
852 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200853 ret = mbedtls_snprintf( p, n, "...." );
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200854 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200855 }
856
857 return( (int) ( size - n ) );
858}
859
860/*
Manuel Pégourié-Gonnard91136032014-06-05 15:41:39 +0200861 * Helper for writing signature algorithms
Manuel Pégourié-Gonnardcac31ee2014-01-25 11:50:59 +0100862 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200863int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid,
864 mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
Manuel Pégourié-Gonnard91136032014-06-05 15:41:39 +0200865 const void *sig_opts )
Manuel Pégourié-Gonnardcac31ee2014-01-25 11:50:59 +0100866{
867 int ret;
868 char *p = buf;
869 size_t n = size;
870 const char *desc = NULL;
871
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200872 ret = mbedtls_oid_get_sig_alg_desc( sig_oid, &desc );
Manuel Pégourié-Gonnardcac31ee2014-01-25 11:50:59 +0100873 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200874 ret = mbedtls_snprintf( p, n, "???" );
Manuel Pégourié-Gonnardcac31ee2014-01-25 11:50:59 +0100875 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200876 ret = mbedtls_snprintf( p, n, "%s", desc );
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200877 MBEDTLS_X509_SAFE_SNPRINTF;
Manuel Pégourié-Gonnardcac31ee2014-01-25 11:50:59 +0100878
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200879#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
880 if( pk_alg == MBEDTLS_PK_RSASSA_PSS )
Manuel Pégourié-Gonnardcac31ee2014-01-25 11:50:59 +0100881 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200882 const mbedtls_pk_rsassa_pss_options *pss_opts;
883 const mbedtls_md_info_t *md_info, *mgf_md_info;
Manuel Pégourié-Gonnardcac31ee2014-01-25 11:50:59 +0100884
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200885 pss_opts = (const mbedtls_pk_rsassa_pss_options *) sig_opts;
Manuel Pégourié-Gonnardcac31ee2014-01-25 11:50:59 +0100886
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200887 md_info = mbedtls_md_info_from_type( md_alg );
888 mgf_md_info = mbedtls_md_info_from_type( pss_opts->mgf1_hash_id );
Manuel Pégourié-Gonnardcac31ee2014-01-25 11:50:59 +0100889
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200890 ret = mbedtls_snprintf( p, n, " (%s, MGF1-%s, 0x%02X)",
891 md_info ? mbedtls_md_get_name( md_info ) : "???",
892 mgf_md_info ? mbedtls_md_get_name( mgf_md_info ) : "???",
Manuel Pégourié-Gonnard91136032014-06-05 15:41:39 +0200893 pss_opts->expected_salt_len );
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200894 MBEDTLS_X509_SAFE_SNPRINTF;
Manuel Pégourié-Gonnardcac31ee2014-01-25 11:50:59 +0100895 }
896#else
897 ((void) pk_alg);
Manuel Pégourié-Gonnard91136032014-06-05 15:41:39 +0200898 ((void) md_alg);
899 ((void) sig_opts);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200900#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
Manuel Pégourié-Gonnardcac31ee2014-01-25 11:50:59 +0100901
Sander Niemeijeref5087d2014-08-16 12:45:52 +0200902 return( (int)( size - n ) );
Manuel Pégourié-Gonnardcac31ee2014-01-25 11:50:59 +0100903}
904
905/*
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200906 * Helper for writing "RSA key size", "EC key size", etc
907 */
Manuel Pégourié-Gonnardfb317c52015-06-18 16:25:56 +0200908int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200909{
910 char *p = buf;
Manuel Pégourié-Gonnardfb317c52015-06-18 16:25:56 +0200911 size_t n = buf_size;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200912 int ret;
913
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200914 ret = mbedtls_snprintf( p, n, "%s key size", name );
Manuel Pégourié-Gonnard16853682015-06-22 11:12:02 +0200915 MBEDTLS_X509_SAFE_SNPRINTF;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200916
917 return( 0 );
918}
919
Manuel Pégourié-Gonnard60c793b2015-06-18 20:52:58 +0200920#if defined(MBEDTLS_HAVE_TIME_DATE)
Manuel Pégourié-Gonnard57e10d72015-06-22 18:59:21 +0200921/*
922 * Set the time structure to the current time.
923 * Return 0 on success, non-zero on failure.
924 */
925#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
Manuel Pégourié-Gonnard864108d2015-05-29 10:11:03 +0200926static int x509_get_current_time( mbedtls_x509_time *now )
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100927{
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200928 SYSTEMTIME st;
929
Paul Bakker66d5d072014-06-17 16:39:18 +0200930 GetSystemTime( &st );
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200931
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100932 now->year = st.wYear;
Manuel Pégourié-Gonnard864108d2015-05-29 10:11:03 +0200933 now->mon = st.wMonth;
934 now->day = st.wDay;
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100935 now->hour = st.wHour;
Manuel Pégourié-Gonnard864108d2015-05-29 10:11:03 +0200936 now->min = st.wMinute;
937 now->sec = st.wSecond;
Manuel Pégourié-Gonnard57e10d72015-06-22 18:59:21 +0200938
939 return( 0 );
940}
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200941#else
Manuel Pégourié-Gonnard57e10d72015-06-22 18:59:21 +0200942static int x509_get_current_time( mbedtls_x509_time *now )
943{
Manuel Pégourié-Gonnard864108d2015-05-29 10:11:03 +0200944 struct tm *lt;
SimonBd5800b72016-04-26 07:43:27 +0100945 mbedtls_time_t tt;
Manuel Pégourié-Gonnard57e10d72015-06-22 18:59:21 +0200946 int ret = 0;
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200947
Manuel Pégourié-Gonnard864108d2015-05-29 10:11:03 +0200948#if defined(MBEDTLS_THREADING_C)
949 if( mbedtls_mutex_lock( &mbedtls_threading_gmtime_mutex ) != 0 )
950 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
951#endif
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200952
SimonBd5800b72016-04-26 07:43:27 +0100953 tt = mbedtls_time( NULL );
Manuel Pégourié-Gonnard864108d2015-05-29 10:11:03 +0200954 lt = gmtime( &tt );
955
Manuel Pégourié-Gonnard57e10d72015-06-22 18:59:21 +0200956 if( lt == NULL )
957 ret = -1;
958 else
959 {
960 now->year = lt->tm_year + 1900;
961 now->mon = lt->tm_mon + 1;
962 now->day = lt->tm_mday;
963 now->hour = lt->tm_hour;
964 now->min = lt->tm_min;
965 now->sec = lt->tm_sec;
966 }
Manuel Pégourié-Gonnard864108d2015-05-29 10:11:03 +0200967
968#if defined(MBEDTLS_THREADING_C)
969 if( mbedtls_mutex_unlock( &mbedtls_threading_gmtime_mutex ) != 0 )
970 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
971#endif
972
Manuel Pégourié-Gonnard57e10d72015-06-22 18:59:21 +0200973 return( ret );
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100974}
Manuel Pégourié-Gonnard57e10d72015-06-22 18:59:21 +0200975#endif /* _WIN32 && !EFIX64 && !EFI32 */
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200976
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100977/*
978 * Return 0 if before <= after, 1 otherwise
979 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200980static int x509_check_time( const mbedtls_x509_time *before, const mbedtls_x509_time *after )
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100981{
982 if( before->year > after->year )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200983 return( 1 );
984
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100985 if( before->year == after->year &&
986 before->mon > after->mon )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200987 return( 1 );
988
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100989 if( before->year == after->year &&
990 before->mon == after->mon &&
991 before->day > after->day )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200992 return( 1 );
993
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +0100994 if( before->year == after->year &&
995 before->mon == after->mon &&
996 before->day == after->day &&
997 before->hour > after->hour )
Paul Bakker7c6b2c32013-09-16 13:49:26 +0200998 return( 1 );
999
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +01001000 if( before->year == after->year &&
1001 before->mon == after->mon &&
1002 before->day == after->day &&
1003 before->hour == after->hour &&
1004 before->min > after->min )
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001005 return( 1 );
1006
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +01001007 if( before->year == after->year &&
1008 before->mon == after->mon &&
1009 before->day == after->day &&
1010 before->hour == after->hour &&
1011 before->min == after->min &&
1012 before->sec > after->sec )
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001013 return( 1 );
1014
1015 return( 0 );
1016}
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +01001017
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +01001018int mbedtls_x509_time_is_past( const mbedtls_x509_time *to )
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +01001019{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001020 mbedtls_x509_time now;
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +01001021
Manuel Pégourié-Gonnard864108d2015-05-29 10:11:03 +02001022 if( x509_get_current_time( &now ) != 0 )
Manuel Pégourié-Gonnarde7e89842015-06-22 19:15:32 +02001023 return( 1 );
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +01001024
1025 return( x509_check_time( &now, to ) );
1026}
1027
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +01001028int mbedtls_x509_time_is_future( const mbedtls_x509_time *from )
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +01001029{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001030 mbedtls_x509_time now;
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +01001031
Manuel Pégourié-Gonnard864108d2015-05-29 10:11:03 +02001032 if( x509_get_current_time( &now ) != 0 )
Manuel Pégourié-Gonnarde7e89842015-06-22 19:15:32 +02001033 return( 1 );
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +01001034
1035 return( x509_check_time( from, &now ) );
1036}
1037
Manuel Pégourié-Gonnard60c793b2015-06-18 20:52:58 +02001038#else /* MBEDTLS_HAVE_TIME_DATE */
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +01001039
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +01001040int mbedtls_x509_time_is_past( const mbedtls_x509_time *to )
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001041{
1042 ((void) to);
1043 return( 0 );
1044}
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +01001045
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +01001046int mbedtls_x509_time_is_future( const mbedtls_x509_time *from )
Manuel Pégourié-Gonnard6304f782014-03-10 12:26:11 +01001047{
1048 ((void) from);
1049 return( 0 );
1050}
Manuel Pégourié-Gonnard60c793b2015-06-18 20:52:58 +02001051#endif /* MBEDTLS_HAVE_TIME_DATE */
Paul Bakker7c6b2c32013-09-16 13:49:26 +02001052
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001053#if defined(MBEDTLS_SELF_TEST)
Paul Bakkere9e6ae32013-09-16 22:53:25 +02001054
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00001055#include "mbedtls/x509_crt.h"
1056#include "mbedtls/certs.h"
Paul Bakkere9e6ae32013-09-16 22:53:25 +02001057
1058/*
1059 * Checkup routine
1060 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001061int mbedtls_x509_self_test( int verbose )
Paul Bakkere9e6ae32013-09-16 22:53:25 +02001062{
Junhwan Parke5d01632018-10-17 21:01:08 +09001063 int ret = 0;
Gilles Peskine750c3532017-05-05 18:56:30 +02001064#if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_SHA256_C)
Manuel Pégourié-Gonnarde6ef16f2015-05-11 19:54:43 +02001065 uint32_t flags;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001066 mbedtls_x509_crt cacert;
1067 mbedtls_x509_crt clicert;
Paul Bakkere9e6ae32013-09-16 22:53:25 +02001068
1069 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001070 mbedtls_printf( " X.509 certificate load: " );
Paul Bakkere9e6ae32013-09-16 22:53:25 +02001071
Junhwan Parke5d01632018-10-17 21:01:08 +09001072 mbedtls_x509_crt_init( &cacert );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001073 mbedtls_x509_crt_init( &clicert );
Paul Bakkere9e6ae32013-09-16 22:53:25 +02001074
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001075 ret = mbedtls_x509_crt_parse( &clicert, (const unsigned char *) mbedtls_test_cli_crt,
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +02001076 mbedtls_test_cli_crt_len );
Paul Bakkere9e6ae32013-09-16 22:53:25 +02001077 if( ret != 0 )
1078 {
1079 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001080 mbedtls_printf( "failed\n" );
Paul Bakkere9e6ae32013-09-16 22:53:25 +02001081
Junhwan Parke5d01632018-10-17 21:01:08 +09001082 goto cleanup;
Paul Bakkere9e6ae32013-09-16 22:53:25 +02001083 }
1084
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001085 ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_ca_crt,
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +02001086 mbedtls_test_ca_crt_len );
Paul Bakkere9e6ae32013-09-16 22:53:25 +02001087 if( ret != 0 )
1088 {
1089 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001090 mbedtls_printf( "failed\n" );
Paul Bakkere9e6ae32013-09-16 22:53:25 +02001091
Junhwan Parke5d01632018-10-17 21:01:08 +09001092 goto cleanup;
Paul Bakkere9e6ae32013-09-16 22:53:25 +02001093 }
1094
1095 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001096 mbedtls_printf( "passed\n X.509 signature verify: ");
Paul Bakkere9e6ae32013-09-16 22:53:25 +02001097
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001098 ret = mbedtls_x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL );
Paul Bakkere9e6ae32013-09-16 22:53:25 +02001099 if( ret != 0 )
1100 {
1101 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001102 mbedtls_printf( "failed\n" );
Paul Bakkere9e6ae32013-09-16 22:53:25 +02001103
Junhwan Parke5d01632018-10-17 21:01:08 +09001104 goto cleanup;
Paul Bakkere9e6ae32013-09-16 22:53:25 +02001105 }
1106
1107 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001108 mbedtls_printf( "passed\n\n");
Paul Bakkere9e6ae32013-09-16 22:53:25 +02001109
Junhwan Parke5d01632018-10-17 21:01:08 +09001110cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001111 mbedtls_x509_crt_free( &cacert );
1112 mbedtls_x509_crt_free( &clicert );
Paul Bakkere9e6ae32013-09-16 22:53:25 +02001113#else
1114 ((void) verbose);
Simon Butcher2c3351e2020-03-27 16:55:35 +00001115#endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA256_C */
Junhwan Parke5d01632018-10-17 21:01:08 +09001116 return( ret );
Paul Bakkere9e6ae32013-09-16 22:53:25 +02001117}
1118
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001119#endif /* MBEDTLS_SELF_TEST */
Paul Bakkere9e6ae32013-09-16 22:53:25 +02001120
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001121#endif /* MBEDTLS_X509_USE_C */