2009-01-03 22:22:43 +01:00
|
|
|
/*
|
2014-06-12 22:34:55 +02:00
|
|
|
* X.509 certificate parsing and verification
|
2009-01-03 22:22:43 +01:00
|
|
|
*
|
2015-07-27 11:11:48 +02:00
|
|
|
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
2015-09-04 14:21:07 +02:00
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
2010-07-18 22:36:00 +02:00
|
|
|
*
|
2015-09-04 14:21:07 +02: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
|
2010-07-18 22:36:00 +02:00
|
|
|
*
|
2015-09-04 14:21:07 +02:00
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
2009-01-03 22:22:43 +01:00
|
|
|
*
|
2015-09-04 14:21:07 +02:00
|
|
|
* 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.
|
2009-01-03 22:22:43 +01:00
|
|
|
*
|
2015-09-04 14:21:07 +02:00
|
|
|
* This file is part of mbed TLS (https://tls.mbed.org)
|
2009-01-03 22:22:43 +01:00
|
|
|
*/
|
|
|
|
/*
|
2012-02-16 16:28:14 +01:00
|
|
|
* The ITU-T X.509 standard defines a certificate format for PKI.
|
2009-01-03 22:22:43 +01:00
|
|
|
*
|
2014-06-12 22:34:55 +02:00
|
|
|
* http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
|
|
|
|
* http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
|
|
|
|
* http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
|
2009-01-03 22:22:43 +01:00
|
|
|
*
|
|
|
|
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
|
|
|
|
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
|
2017-07-03 18:30:43 +02:00
|
|
|
*
|
|
|
|
* [SIRO] https://cabforum.org/wp-content/uploads/Chunghwatelecom201503cabforumV4.pdf
|
2009-01-03 22:22:43 +01:00
|
|
|
*/
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
2015-03-09 18:05:11 +01:00
|
|
|
#include "mbedtls/config.h"
|
2014-04-29 12:39:06 +02:00
|
|
|
#else
|
2015-04-08 12:49:31 +02:00
|
|
|
#include MBEDTLS_CONFIG_FILE
|
2014-04-29 12:39:06 +02:00
|
|
|
#endif
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2015-03-09 18:05:11 +01:00
|
|
|
#include "mbedtls/x509_crt.h"
|
2019-05-02 14:05:58 +02:00
|
|
|
#include "mbedtls/x509_internal.h"
|
2015-03-09 18:05:11 +01:00
|
|
|
#include "mbedtls/oid.h"
|
2018-04-17 16:51:09 +02:00
|
|
|
#include "mbedtls/platform_util.h"
|
2015-02-06 14:43:58 +01:00
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
#if defined(MBEDTLS_PEM_PARSE_C)
|
2015-03-09 18:05:11 +01:00
|
|
|
#include "mbedtls/pem.h"
|
2013-09-15 20:43:33 +02:00
|
|
|
#endif
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
#if defined(MBEDTLS_PLATFORM_C)
|
2015-03-09 18:05:11 +01:00
|
|
|
#include "mbedtls/platform.h"
|
2013-07-03 13:37:05 +02:00
|
|
|
#else
|
2018-10-03 16:11:19 +02:00
|
|
|
#include <stdio.h>
|
2015-02-06 14:43:58 +01:00
|
|
|
#include <stdlib.h>
|
2015-04-08 12:49:31 +02:00
|
|
|
#define mbedtls_free free
|
2015-05-26 16:04:06 +02:00
|
|
|
#define mbedtls_calloc calloc
|
2015-04-08 12:49:31 +02:00
|
|
|
#define mbedtls_snprintf snprintf
|
2013-07-03 13:37:05 +02:00
|
|
|
#endif
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
#if defined(MBEDTLS_THREADING_C)
|
2015-03-09 18:05:11 +01:00
|
|
|
#include "mbedtls/threading.h"
|
2013-11-28 17:11:54 +01:00
|
|
|
#endif
|
|
|
|
|
2013-10-28 18:48:30 +01:00
|
|
|
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
|
2011-11-18 15:26:47 +01:00
|
|
|
#include <windows.h>
|
|
|
|
#else
|
2009-01-03 22:22:43 +01:00
|
|
|
#include <time.h>
|
2011-11-18 15:26:47 +01:00
|
|
|
#endif
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
#if defined(MBEDTLS_FS_IO)
|
2015-02-06 14:43:58 +01:00
|
|
|
#include <stdio.h>
|
2014-04-04 15:08:20 +02:00
|
|
|
#if !defined(_WIN32) || defined(EFIX64) || defined(EFI32)
|
2012-06-04 14:46:42 +02:00
|
|
|
#include <sys/types.h>
|
2013-06-24 19:22:42 +02:00
|
|
|
#include <sys/stat.h>
|
2012-06-04 14:46:42 +02:00
|
|
|
#include <dirent.h>
|
2015-02-06 14:43:58 +01:00
|
|
|
#endif /* !_WIN32 || EFIX64 || EFI32 */
|
2011-04-25 17:28:35 +02:00
|
|
|
#endif
|
|
|
|
|
2019-03-04 16:13:45 +01:00
|
|
|
#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING)
|
|
|
|
static void x509_buf_to_buf_raw( mbedtls_x509_buf_raw *dst,
|
|
|
|
mbedtls_x509_buf const *src )
|
|
|
|
{
|
|
|
|
dst->p = src->p;
|
|
|
|
dst->len = src->len;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void x509_buf_raw_to_buf( mbedtls_x509_buf *dst,
|
|
|
|
mbedtls_x509_buf_raw const *src )
|
|
|
|
{
|
|
|
|
dst->p = src->p;
|
|
|
|
dst->len = src->len;
|
|
|
|
}
|
|
|
|
#endif /* MBEDTLS_X509_ON_DEMAND_PARSING */
|
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
static int x509_crt_parse_frame( unsigned char *start,
|
|
|
|
unsigned char *end,
|
|
|
|
mbedtls_x509_crt_frame *frame );
|
2019-05-13 14:53:21 +02:00
|
|
|
static int x509_crt_subject_from_frame( mbedtls_x509_crt_frame const *frame,
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
mbedtls_x509_name *subject );
|
2019-05-13 14:53:21 +02:00
|
|
|
static int x509_crt_issuer_from_frame( mbedtls_x509_crt_frame const *frame,
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
mbedtls_x509_name *issuer );
|
2019-05-13 14:53:21 +02:00
|
|
|
static int x509_crt_subject_alt_from_frame( mbedtls_x509_crt_frame const *frame,
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
mbedtls_x509_sequence *subject_alt );
|
2019-05-13 14:53:21 +02:00
|
|
|
static int x509_crt_ext_key_usage_from_frame( mbedtls_x509_crt_frame const *frame,
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
mbedtls_x509_sequence *ext_key_usage );
|
|
|
|
|
2019-03-05 16:35:31 +01:00
|
|
|
int mbedtls_x509_crt_flush_cache_pk( mbedtls_x509_crt const *crt )
|
|
|
|
{
|
|
|
|
#if defined(MBEDTLS_THREADING_C)
|
|
|
|
if( mbedtls_mutex_lock( &crt->cache->pk_mutex ) != 0 )
|
|
|
|
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
2019-06-28 11:34:23 +02:00
|
|
|
#endif
|
2019-06-28 15:45:26 +02:00
|
|
|
|
|
|
|
#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \
|
|
|
|
defined(MBEDTLS_THREADING_C)
|
|
|
|
/* Can only free the PK context if nobody is using it.
|
|
|
|
* If MBEDTLS_X509_ALWAYS_FLUSH is set, nested uses
|
|
|
|
* of xxx_acquire() are prohibited, and no reference
|
|
|
|
* counting is needed. Also, notice that the code-path
|
|
|
|
* below is safe if the cache isn't filled. */
|
2019-05-28 17:11:43 +02:00
|
|
|
if( crt->cache->pk_readers == 0 )
|
2019-06-28 15:45:26 +02:00
|
|
|
#endif /* !MBEDTLS_X509_ALWAYS_FLUSH ||
|
|
|
|
MBEDTLS_THREADING_C */
|
2019-05-28 17:11:43 +02:00
|
|
|
{
|
2019-03-05 16:35:31 +01:00
|
|
|
#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING)
|
2019-05-28 17:11:43 +02:00
|
|
|
/* The cache holds a shallow copy of the PK context
|
|
|
|
* in the legacy struct, so don't free PK context. */
|
|
|
|
mbedtls_free( crt->cache->pk );
|
2019-03-05 16:35:31 +01:00
|
|
|
#else
|
2019-05-28 17:11:43 +02:00
|
|
|
mbedtls_pk_free( crt->cache->pk );
|
|
|
|
mbedtls_free( crt->cache->pk );
|
2019-03-05 16:35:31 +01:00
|
|
|
#endif /* MBEDTLS_X509_ON_DEMAND_PARSING */
|
2019-05-28 17:11:43 +02:00
|
|
|
crt->cache->pk = NULL;
|
|
|
|
}
|
2019-03-05 16:35:31 +01:00
|
|
|
|
|
|
|
#if defined(MBEDTLS_THREADING_C)
|
|
|
|
if( mbedtls_mutex_unlock( &crt->cache->pk_mutex ) != 0 )
|
|
|
|
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
|
|
|
#endif
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
int mbedtls_x509_crt_flush_cache_frame( mbedtls_x509_crt const *crt )
|
|
|
|
{
|
|
|
|
#if defined(MBEDTLS_THREADING_C)
|
|
|
|
if( mbedtls_mutex_lock( &crt->cache->frame_mutex ) != 0 )
|
|
|
|
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
2019-06-28 11:34:23 +02:00
|
|
|
#endif
|
2019-03-05 16:35:31 +01:00
|
|
|
|
2019-06-28 15:45:26 +02:00
|
|
|
#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \
|
|
|
|
defined(MBEDTLS_THREADING_C)
|
|
|
|
/* Can only free the PK context if nobody is using it.
|
|
|
|
* If MBEDTLS_X509_ALWAYS_FLUSH is set, nested uses
|
|
|
|
* of xxx_acquire() are prohibited, and no reference
|
|
|
|
* counting is needed. Also, notice that the code-path
|
|
|
|
* below is safe if the cache isn't filled. */
|
2019-05-28 17:11:43 +02:00
|
|
|
if( crt->cache->frame_readers == 0 )
|
2019-06-28 15:45:26 +02:00
|
|
|
#endif /* !MBEDTLS_X509_ALWAYS_FLUSH ||
|
|
|
|
MBEDTLS_THREADING_C */
|
2019-05-28 17:11:43 +02:00
|
|
|
{
|
|
|
|
mbedtls_free( crt->cache->frame );
|
|
|
|
crt->cache->frame = NULL;
|
|
|
|
}
|
2019-03-05 16:35:31 +01:00
|
|
|
|
|
|
|
#if defined(MBEDTLS_THREADING_C)
|
|
|
|
if( mbedtls_mutex_unlock( &crt->cache->frame_mutex ) != 0 )
|
|
|
|
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
|
|
|
|
#endif
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
int mbedtls_x509_crt_flush_cache( mbedtls_x509_crt const *crt )
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
ret = mbedtls_x509_crt_flush_cache_frame( crt );
|
|
|
|
if( ret != 0 )
|
|
|
|
return( ret );
|
|
|
|
ret = mbedtls_x509_crt_flush_cache_pk( crt );
|
|
|
|
if( ret != 0 )
|
|
|
|
return( ret );
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
2019-03-04 12:52:23 +01:00
|
|
|
static int x509_crt_frame_parse_ext( mbedtls_x509_crt_frame *frame );
|
2019-06-28 11:46:43 +02:00
|
|
|
|
2019-02-25 14:50:14 +01:00
|
|
|
int mbedtls_x509_crt_cache_provide_frame( mbedtls_x509_crt const *crt )
|
2019-02-25 15:53:14 +01:00
|
|
|
{
|
2019-02-25 14:50:14 +01:00
|
|
|
mbedtls_x509_crt_cache *cache = crt->cache;
|
2019-02-25 15:53:14 +01:00
|
|
|
mbedtls_x509_crt_frame *frame;
|
|
|
|
|
2019-03-05 16:29:23 +01:00
|
|
|
if( cache->frame != NULL )
|
2019-06-28 15:45:26 +02:00
|
|
|
{
|
2019-07-02 14:37:12 +02:00
|
|
|
#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \
|
|
|
|
defined(MBEDTLS_THREADING_C)
|
2019-03-05 16:29:23 +01:00
|
|
|
return( 0 );
|
2019-06-28 15:45:26 +02:00
|
|
|
#else
|
|
|
|
/* If MBEDTLS_X509_ALWAYS_FLUSH is set, we don't
|
|
|
|
* allow nested uses of acquire. */
|
|
|
|
return( MBEDTLS_ERR_X509_FATAL_ERROR );
|
|
|
|
#endif
|
|
|
|
}
|
2019-03-05 16:29:23 +01:00
|
|
|
|
2019-02-25 15:53:14 +01:00
|
|
|
frame = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt_frame ) );
|
|
|
|
if( frame == NULL )
|
|
|
|
return( MBEDTLS_ERR_X509_ALLOC_FAILED );
|
2019-02-25 14:50:14 +01:00
|
|
|
cache->frame = frame;
|
2019-02-25 15:53:14 +01:00
|
|
|
|
2019-03-04 12:52:23 +01:00
|
|
|
#if defined(MBEDTLS_X509_ON_DEMAND_PARSING)
|
|
|
|
/* This would work with !MBEDTLS_X509_ON_DEMAND_PARSING, too,
|
|
|
|
* but is inefficient compared to copying the respective fields
|
|
|
|
* from the legacy mbedtls_x509_crt. */
|
2019-02-25 14:50:14 +01:00
|
|
|
return( x509_crt_parse_frame( crt->raw.p,
|
|
|
|
crt->raw.p + crt->raw.len,
|
|
|
|
frame ) );
|
2019-03-04 12:52:23 +01:00
|
|
|
#else /* MBEDTLS_X509_ON_DEMAND_PARSING */
|
|
|
|
/* Make sure all extension related fields are properly initialized. */
|
|
|
|
frame->ca_istrue = 0;
|
|
|
|
frame->max_pathlen = 0;
|
|
|
|
frame->ext_types = 0;
|
|
|
|
frame->version = crt->version;
|
|
|
|
frame->sig_md = crt->sig_md;
|
|
|
|
frame->sig_pk = crt->sig_pk;
|
2019-06-25 10:39:21 +02:00
|
|
|
|
|
|
|
#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME)
|
2019-03-04 12:52:23 +01:00
|
|
|
frame->valid_from = crt->valid_from;
|
|
|
|
frame->valid_to = crt->valid_to;
|
2019-06-25 10:39:21 +02:00
|
|
|
#endif /* !MBEDTLS_X509_CRT_REMOVE_TIME */
|
|
|
|
|
2019-03-04 16:13:45 +01:00
|
|
|
x509_buf_to_buf_raw( &frame->raw, &crt->raw );
|
|
|
|
x509_buf_to_buf_raw( &frame->tbs, &crt->tbs );
|
|
|
|
x509_buf_to_buf_raw( &frame->serial, &crt->serial );
|
|
|
|
x509_buf_to_buf_raw( &frame->pubkey_raw, &crt->pk_raw );
|
|
|
|
x509_buf_to_buf_raw( &frame->issuer_raw, &crt->issuer_raw );
|
|
|
|
x509_buf_to_buf_raw( &frame->subject_raw, &crt->subject_raw );
|
2019-06-25 11:19:58 +02:00
|
|
|
#if !defined(MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID)
|
2019-03-04 16:13:45 +01:00
|
|
|
x509_buf_to_buf_raw( &frame->subject_id, &crt->subject_id );
|
|
|
|
x509_buf_to_buf_raw( &frame->issuer_id, &crt->issuer_id );
|
2019-06-25 11:19:58 +02:00
|
|
|
#endif /* !MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID */
|
2019-03-04 16:13:45 +01:00
|
|
|
x509_buf_to_buf_raw( &frame->sig, &crt->sig );
|
|
|
|
x509_buf_to_buf_raw( &frame->v3_ext, &crt->v3_ext );
|
2019-03-04 12:52:23 +01:00
|
|
|
|
|
|
|
/* The legacy CRT structure doesn't explicitly contain
|
|
|
|
* the `AlgorithmIdentifier` bounds; however, those can
|
|
|
|
* be inferred from the surrounding (mandatory) `SerialNumber`
|
|
|
|
* and `Issuer` fields. */
|
|
|
|
frame->sig_alg.p = crt->serial.p + crt->serial.len;
|
|
|
|
frame->sig_alg.len = crt->issuer_raw.p - frame->sig_alg.p;
|
|
|
|
|
|
|
|
return( x509_crt_frame_parse_ext( frame ) );
|
|
|
|
#endif /* !MBEDTLS_X509_ON_DEMAND_PARSING */
|
2019-02-25 14:50:14 +01:00
|
|
|
}
|
2019-02-25 15:53:14 +01:00
|
|
|
|
2019-02-25 14:50:14 +01:00
|
|
|
int mbedtls_x509_crt_cache_provide_pk( mbedtls_x509_crt const *crt )
|
|
|
|
{
|
|
|
|
mbedtls_x509_crt_cache *cache = crt->cache;
|
|
|
|
mbedtls_pk_context *pk;
|
|
|
|
|
2019-03-05 16:29:23 +01:00
|
|
|
if( cache->pk != NULL )
|
2019-06-28 15:45:26 +02:00
|
|
|
{
|
2019-07-02 14:37:12 +02:00
|
|
|
#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \
|
|
|
|
defined(MBEDTLS_THREADING_C)
|
2019-03-05 16:29:23 +01:00
|
|
|
return( 0 );
|
2019-06-28 15:45:26 +02:00
|
|
|
#else
|
|
|
|
/* If MBEDTLS_X509_ALWAYS_FLUSH is set, we don't
|
|
|
|
* allow nested uses of acquire. */
|
|
|
|
return( MBEDTLS_ERR_X509_FATAL_ERROR );
|
|
|
|
#endif
|
|
|
|
}
|
2019-03-05 16:29:23 +01:00
|
|
|
|
2019-02-25 14:50:14 +01:00
|
|
|
pk = mbedtls_calloc( 1, sizeof( mbedtls_pk_context ) );
|
|
|
|
if( pk == NULL )
|
|
|
|
return( MBEDTLS_ERR_X509_ALLOC_FAILED );
|
|
|
|
cache->pk = pk;
|
2019-02-28 14:23:38 +01:00
|
|
|
|
|
|
|
#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING)
|
|
|
|
*pk = crt->pk;
|
2019-02-25 15:53:14 +01:00
|
|
|
return( 0 );
|
2019-02-28 14:23:38 +01:00
|
|
|
#else
|
|
|
|
{
|
|
|
|
mbedtls_x509_buf_raw pk_raw = cache->pk_raw;
|
|
|
|
return( mbedtls_pk_parse_subpubkey( &pk_raw.p,
|
|
|
|
pk_raw.p + pk_raw.len,
|
|
|
|
pk ) );
|
|
|
|
}
|
|
|
|
#endif /* MBEDTLS_X509_ON_DEMAND_PARSING */
|
2019-02-25 15:53:14 +01:00
|
|
|
}
|
|
|
|
|
2019-02-25 14:50:14 +01:00
|
|
|
static void x509_crt_cache_init( mbedtls_x509_crt_cache *cache )
|
2019-02-25 15:53:14 +01:00
|
|
|
{
|
2019-02-25 14:50:14 +01:00
|
|
|
memset( cache, 0, sizeof( *cache ) );
|
|
|
|
#if defined(MBEDTLS_THREADING_C)
|
|
|
|
mbedtls_mutex_init( &cache->frame_mutex );
|
|
|
|
mbedtls_mutex_init( &cache->pk_mutex );
|
|
|
|
#endif
|
2019-02-25 15:53:14 +01:00
|
|
|
}
|
2019-02-25 14:50:14 +01:00
|
|
|
|
|
|
|
static void x509_crt_cache_clear_pk( mbedtls_x509_crt_cache *cache )
|
2019-02-25 15:53:14 +01:00
|
|
|
{
|
2019-02-28 14:23:38 +01:00
|
|
|
#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING)
|
2019-02-25 14:50:14 +01:00
|
|
|
/* The cache holds a shallow copy of the PK context
|
|
|
|
* in the legacy struct, so don't free PK context. */
|
|
|
|
mbedtls_free( cache->pk );
|
2019-02-28 14:23:38 +01:00
|
|
|
#else
|
|
|
|
mbedtls_pk_free( cache->pk );
|
|
|
|
mbedtls_free( cache->pk );
|
|
|
|
#endif /* MBEDTLS_X509_ON_DEMAND_PARSING */
|
|
|
|
|
2019-02-25 14:50:14 +01:00
|
|
|
cache->pk = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void x509_crt_cache_clear_frame( mbedtls_x509_crt_cache *cache )
|
|
|
|
{
|
|
|
|
mbedtls_free( cache->frame );
|
|
|
|
cache->frame = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void x509_crt_cache_free( mbedtls_x509_crt_cache *cache )
|
|
|
|
{
|
|
|
|
if( cache == NULL )
|
|
|
|
return;
|
|
|
|
|
|
|
|
#if defined(MBEDTLS_THREADING_C)
|
|
|
|
mbedtls_mutex_free( &cache->frame_mutex );
|
|
|
|
mbedtls_mutex_free( &cache->pk_mutex );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
x509_crt_cache_clear_frame( cache );
|
|
|
|
x509_crt_cache_clear_pk( cache );
|
|
|
|
|
|
|
|
memset( cache, 0, sizeof( *cache ) );
|
2019-02-25 15:53:14 +01:00
|
|
|
}
|
|
|
|
|
2019-02-27 18:33:14 +01:00
|
|
|
int mbedtls_x509_crt_get_subject_alt_names( mbedtls_x509_crt const *crt,
|
|
|
|
mbedtls_x509_sequence **subj_alt )
|
|
|
|
{
|
|
|
|
int ret;
|
2019-05-20 17:26:34 +02:00
|
|
|
mbedtls_x509_crt_frame const *frame;
|
2019-02-27 18:33:14 +01:00
|
|
|
mbedtls_x509_sequence *seq;
|
|
|
|
|
|
|
|
ret = mbedtls_x509_crt_frame_acquire( crt, &frame );
|
|
|
|
if( ret != 0 )
|
|
|
|
return( ret );
|
|
|
|
|
|
|
|
seq = mbedtls_calloc( 1, sizeof( mbedtls_x509_sequence ) );
|
|
|
|
if( seq == NULL )
|
|
|
|
ret = MBEDTLS_ERR_X509_ALLOC_FAILED;
|
|
|
|
else
|
|
|
|
ret = x509_crt_subject_alt_from_frame( frame, seq );
|
|
|
|
|
2019-03-05 14:50:56 +01:00
|
|
|
mbedtls_x509_crt_frame_release( crt );
|
2019-02-27 18:33:14 +01:00
|
|
|
|
|
|
|
*subj_alt = seq;
|
|
|
|
return( ret );
|
|
|
|
}
|
|
|
|
|
|
|
|
int mbedtls_x509_crt_get_ext_key_usage( mbedtls_x509_crt const *crt,
|
|
|
|
mbedtls_x509_sequence **ext_key_usage )
|
|
|
|
{
|
|
|
|
int ret;
|
2019-05-20 17:26:34 +02:00
|
|
|
mbedtls_x509_crt_frame const *frame;
|
2019-02-27 18:33:14 +01:00
|
|
|
mbedtls_x509_sequence *seq;
|
|
|
|
|
|
|
|
ret = mbedtls_x509_crt_frame_acquire( crt, &frame );
|
|
|
|
if( ret != 0 )
|
|
|
|
return( ret );
|
|
|
|
|
|
|
|
seq = mbedtls_calloc( 1, sizeof( mbedtls_x509_sequence ) );
|
|
|
|
if( seq == NULL )
|
|
|
|
ret = MBEDTLS_ERR_X509_ALLOC_FAILED;
|
|
|
|
else
|
|
|
|
ret = x509_crt_ext_key_usage_from_frame( frame, seq );
|
|
|
|
|
2019-03-05 14:50:56 +01:00
|
|
|
mbedtls_x509_crt_frame_release( crt );
|
2019-02-27 18:33:14 +01:00
|
|
|
|
|
|
|
*ext_key_usage = seq;
|
|
|
|
return( ret );
|
|
|
|
}
|
|
|
|
|
2019-02-26 19:50:49 +01:00
|
|
|
int mbedtls_x509_crt_get_subject( mbedtls_x509_crt const *crt,
|
|
|
|
mbedtls_x509_name **subject )
|
|
|
|
{
|
|
|
|
int ret;
|
2019-05-20 17:26:34 +02:00
|
|
|
mbedtls_x509_crt_frame const *frame;
|
2019-02-26 19:50:49 +01:00
|
|
|
mbedtls_x509_name *name;
|
|
|
|
|
|
|
|
ret = mbedtls_x509_crt_frame_acquire( crt, &frame );
|
|
|
|
if( ret != 0 )
|
|
|
|
return( ret );
|
|
|
|
|
|
|
|
name = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) );
|
|
|
|
if( name == NULL )
|
|
|
|
ret = MBEDTLS_ERR_X509_ALLOC_FAILED;
|
|
|
|
else
|
|
|
|
ret = x509_crt_subject_from_frame( frame, name );
|
|
|
|
|
2019-03-05 14:50:56 +01:00
|
|
|
mbedtls_x509_crt_frame_release( crt );
|
2019-02-26 19:50:49 +01:00
|
|
|
|
|
|
|
*subject = name;
|
|
|
|
return( ret );
|
|
|
|
}
|
|
|
|
|
|
|
|
int mbedtls_x509_crt_get_issuer( mbedtls_x509_crt const *crt,
|
|
|
|
mbedtls_x509_name **issuer )
|
|
|
|
{
|
|
|
|
int ret;
|
2019-05-20 17:26:34 +02:00
|
|
|
mbedtls_x509_crt_frame const *frame;
|
2019-02-26 19:50:49 +01:00
|
|
|
mbedtls_x509_name *name;
|
|
|
|
|
|
|
|
ret = mbedtls_x509_crt_frame_acquire( crt, &frame );
|
|
|
|
if( ret != 0 )
|
|
|
|
return( ret );
|
|
|
|
|
|
|
|
name = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) );
|
|
|
|
if( name == NULL )
|
|
|
|
ret = MBEDTLS_ERR_X509_ALLOC_FAILED;
|
|
|
|
else
|
|
|
|
ret = x509_crt_issuer_from_frame( frame, name );
|
|
|
|
|
2019-03-05 14:50:56 +01:00
|
|
|
mbedtls_x509_crt_frame_release( crt );
|
2019-02-26 19:50:49 +01:00
|
|
|
|
|
|
|
*issuer = name;
|
|
|
|
return( ret );
|
|
|
|
}
|
|
|
|
|
2019-02-28 14:23:58 +01:00
|
|
|
int mbedtls_x509_crt_get_frame( mbedtls_x509_crt const *crt,
|
|
|
|
mbedtls_x509_crt_frame *dst )
|
|
|
|
{
|
|
|
|
int ret;
|
2019-05-20 17:26:34 +02:00
|
|
|
mbedtls_x509_crt_frame const *frame;
|
2019-02-28 14:23:58 +01:00
|
|
|
ret = mbedtls_x509_crt_frame_acquire( crt, &frame );
|
|
|
|
if( ret != 0 )
|
|
|
|
return( ret );
|
|
|
|
*dst = *frame;
|
2019-03-05 14:50:56 +01:00
|
|
|
mbedtls_x509_crt_frame_release( crt );
|
2019-02-28 14:23:58 +01:00
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
int mbedtls_x509_crt_get_pk( mbedtls_x509_crt const *crt,
|
|
|
|
mbedtls_pk_context *dst )
|
|
|
|
{
|
|
|
|
#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING)
|
|
|
|
mbedtls_x509_buf_raw pk_raw = crt->cache->pk_raw;
|
|
|
|
return( mbedtls_pk_parse_subpubkey( &pk_raw.p,
|
|
|
|
pk_raw.p + pk_raw.len,
|
|
|
|
dst ) );
|
|
|
|
#else /* !MBEDTLS_X509_ON_DEMAND_PARSING */
|
|
|
|
int ret;
|
|
|
|
mbedtls_pk_context *pk;
|
|
|
|
ret = mbedtls_x509_crt_pk_acquire( crt, &pk );
|
|
|
|
if( ret != 0 )
|
|
|
|
return( ret );
|
|
|
|
|
|
|
|
/* Move PK from CRT cache to destination pointer
|
|
|
|
* to avoid a copy. */
|
|
|
|
*dst = *pk;
|
|
|
|
mbedtls_free( crt->cache->pk );
|
|
|
|
crt->cache->pk = NULL;
|
|
|
|
|
2019-03-05 14:50:56 +01:00
|
|
|
mbedtls_x509_crt_pk_release( crt );
|
2019-02-28 14:23:58 +01:00
|
|
|
return( 0 );
|
|
|
|
#endif /* MBEDTLS_X509_ON_DEMAND_PARSING */
|
|
|
|
}
|
|
|
|
|
2017-07-05 13:28:45 +02:00
|
|
|
/*
|
|
|
|
* Item in a verification chain: cert and flags for it
|
|
|
|
*/
|
|
|
|
typedef struct {
|
|
|
|
mbedtls_x509_crt *crt;
|
|
|
|
uint32_t flags;
|
|
|
|
} x509_crt_verify_chain_item;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Max size of verification chain: end-entity + intermediates + trusted root
|
|
|
|
*/
|
|
|
|
#define X509_MAX_VERIFY_CHAIN_SIZE ( MBEDTLS_X509_MAX_INTERMEDIATE_CA + 2 )
|
2014-06-13 17:20:13 +02:00
|
|
|
|
2015-06-15 14:34:59 +02:00
|
|
|
/*
|
|
|
|
* Default profile
|
|
|
|
*/
|
|
|
|
const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default =
|
|
|
|
{
|
2017-05-12 13:16:40 +02:00
|
|
|
#if defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES)
|
2017-05-04 16:17:21 +02:00
|
|
|
/* Allow SHA-1 (weak, but still safe in controlled environments) */
|
2015-06-15 15:33:19 +02:00
|
|
|
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) |
|
2017-05-04 16:17:21 +02:00
|
|
|
#endif
|
|
|
|
/* Only SHA-2 hashes */
|
2015-06-15 15:33:19 +02:00
|
|
|
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) |
|
|
|
|
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
|
|
|
|
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
|
|
|
|
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
|
|
|
|
0xFFFFFFF, /* Any PK alg */
|
|
|
|
0xFFFFFFF, /* Any curve */
|
2015-06-15 14:34:59 +02:00
|
|
|
2048,
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Next-default profile
|
|
|
|
*/
|
2015-06-15 15:33:19 +02:00
|
|
|
const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next =
|
2015-06-15 14:34:59 +02:00
|
|
|
{
|
2015-06-15 15:33:19 +02:00
|
|
|
/* Hashes from SHA-256 and above */
|
|
|
|
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
|
|
|
|
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
|
|
|
|
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
|
|
|
|
0xFFFFFFF, /* Any PK alg */
|
2015-06-15 14:34:59 +02:00
|
|
|
#if defined(MBEDTLS_ECP_C)
|
2015-06-15 15:33:19 +02:00
|
|
|
/* Curves at or above 128-bit security level */
|
|
|
|
MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) |
|
|
|
|
MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ) |
|
|
|
|
MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP521R1 ) |
|
|
|
|
MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP256R1 ) |
|
|
|
|
MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP384R1 ) |
|
|
|
|
MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP512R1 ) |
|
|
|
|
MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256K1 ),
|
2015-06-15 14:34:59 +02:00
|
|
|
#else
|
2015-06-15 15:33:19 +02:00
|
|
|
0,
|
2015-06-15 14:34:59 +02:00
|
|
|
#endif
|
|
|
|
2048,
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* NSA Suite B Profile
|
|
|
|
*/
|
2015-06-15 15:33:19 +02:00
|
|
|
const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb =
|
2015-06-15 14:34:59 +02:00
|
|
|
{
|
2015-06-15 15:33:19 +02:00
|
|
|
/* Only SHA-256 and 384 */
|
|
|
|
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
|
|
|
|
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ),
|
|
|
|
/* Only ECDSA */
|
2018-02-06 14:59:38 +01:00
|
|
|
MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ) |
|
|
|
|
MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECKEY ),
|
2015-06-15 14:34:59 +02:00
|
|
|
#if defined(MBEDTLS_ECP_C)
|
2015-06-15 15:33:19 +02:00
|
|
|
/* Only NIST P-256 and P-384 */
|
|
|
|
MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) |
|
|
|
|
MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ),
|
2015-06-15 14:34:59 +02:00
|
|
|
#else
|
2015-06-15 15:33:19 +02:00
|
|
|
0,
|
2015-06-15 14:34:59 +02:00
|
|
|
#endif
|
2015-06-15 15:33:19 +02:00
|
|
|
0,
|
2015-06-15 14:34:59 +02:00
|
|
|
};
|
|
|
|
|
2015-06-15 16:17:55 +02:00
|
|
|
/*
|
|
|
|
* Check md_alg against profile
|
2017-10-26 10:24:16 +02:00
|
|
|
* Return 0 if md_alg is acceptable for this profile, -1 otherwise
|
2015-06-15 16:17:55 +02:00
|
|
|
*/
|
|
|
|
static int x509_profile_check_md_alg( const mbedtls_x509_crt_profile *profile,
|
|
|
|
mbedtls_md_type_t md_alg )
|
|
|
|
{
|
2018-05-11 11:06:29 +02:00
|
|
|
if( md_alg == MBEDTLS_MD_NONE )
|
|
|
|
return( -1 );
|
|
|
|
|
2015-06-15 16:17:55 +02:00
|
|
|
if( ( profile->allowed_mds & MBEDTLS_X509_ID_FLAG( md_alg ) ) != 0 )
|
|
|
|
return( 0 );
|
|
|
|
|
|
|
|
return( -1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check pk_alg against profile
|
2017-10-26 10:24:16 +02:00
|
|
|
* Return 0 if pk_alg is acceptable for this profile, -1 otherwise
|
2015-06-15 16:17:55 +02:00
|
|
|
*/
|
|
|
|
static int x509_profile_check_pk_alg( const mbedtls_x509_crt_profile *profile,
|
|
|
|
mbedtls_pk_type_t pk_alg )
|
|
|
|
{
|
2018-05-11 11:06:29 +02:00
|
|
|
if( pk_alg == MBEDTLS_PK_NONE )
|
|
|
|
return( -1 );
|
|
|
|
|
2015-06-15 16:17:55 +02:00
|
|
|
if( ( profile->allowed_pks & MBEDTLS_X509_ID_FLAG( pk_alg ) ) != 0 )
|
|
|
|
return( 0 );
|
|
|
|
|
|
|
|
return( -1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check key against profile
|
2017-10-26 10:24:16 +02:00
|
|
|
* Return 0 if pk is acceptable for this profile, -1 otherwise
|
2015-06-15 16:17:55 +02:00
|
|
|
*/
|
|
|
|
static int x509_profile_check_key( const mbedtls_x509_crt_profile *profile,
|
|
|
|
const mbedtls_pk_context *pk )
|
|
|
|
{
|
2017-10-26 10:24:16 +02:00
|
|
|
const mbedtls_pk_type_t pk_alg = mbedtls_pk_get_type( pk );
|
2017-10-24 10:51:26 +02:00
|
|
|
|
2015-06-15 16:17:55 +02:00
|
|
|
#if defined(MBEDTLS_RSA_C)
|
|
|
|
if( pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS )
|
|
|
|
{
|
2015-06-18 16:43:38 +02:00
|
|
|
if( mbedtls_pk_get_bitlen( pk ) >= profile->rsa_min_bitlen )
|
2015-06-15 16:17:55 +02:00
|
|
|
return( 0 );
|
|
|
|
|
|
|
|
return( -1 );
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-10-23 14:08:48 +02:00
|
|
|
#if defined(MBEDTLS_ECP_C)
|
|
|
|
if( pk_alg == MBEDTLS_PK_ECDSA ||
|
|
|
|
pk_alg == MBEDTLS_PK_ECKEY ||
|
|
|
|
pk_alg == MBEDTLS_PK_ECKEY_DH )
|
2015-06-15 16:17:55 +02:00
|
|
|
{
|
2017-10-26 10:24:16 +02:00
|
|
|
const mbedtls_ecp_group_id gid = mbedtls_pk_ec( *pk )->grp.id;
|
2015-06-15 16:17:55 +02:00
|
|
|
|
2018-05-11 11:06:29 +02:00
|
|
|
if( gid == MBEDTLS_ECP_DP_NONE )
|
|
|
|
return( -1 );
|
|
|
|
|
2015-06-15 16:17:55 +02:00
|
|
|
if( ( profile->allowed_curves & MBEDTLS_X509_ID_FLAG( gid ) ) != 0 )
|
|
|
|
return( 0 );
|
|
|
|
|
|
|
|
return( -1 );
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return( -1 );
|
|
|
|
}
|
|
|
|
|
2018-11-02 10:19:16 +01:00
|
|
|
/*
|
|
|
|
* Return 0 if name matches wildcard, -1 otherwise
|
|
|
|
*/
|
2019-02-21 14:10:55 +01:00
|
|
|
static int x509_check_wildcard( char const *cn,
|
|
|
|
size_t cn_len,
|
|
|
|
unsigned char const *buf,
|
|
|
|
size_t buf_len )
|
2018-11-02 10:19:16 +01:00
|
|
|
{
|
|
|
|
size_t i;
|
2019-02-21 14:10:55 +01:00
|
|
|
size_t cn_idx = 0;
|
2018-11-02 10:19:16 +01:00
|
|
|
|
|
|
|
/* We can't have a match if there is no wildcard to match */
|
2019-02-21 14:10:55 +01:00
|
|
|
if( buf_len < 3 || buf[0] != '*' || buf[1] != '.' )
|
2018-11-02 10:19:16 +01:00
|
|
|
return( -1 );
|
|
|
|
|
|
|
|
for( i = 0; i < cn_len; ++i )
|
|
|
|
{
|
|
|
|
if( cn[i] == '.' )
|
|
|
|
{
|
|
|
|
cn_idx = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( cn_idx == 0 )
|
|
|
|
return( -1 );
|
|
|
|
|
2019-02-22 12:46:06 +01:00
|
|
|
if( mbedtls_x509_memcasecmp( buf + 1, cn + cn_idx,
|
|
|
|
buf_len - 1, cn_len - cn_idx ) == 0 )
|
2018-11-02 10:19:16 +01:00
|
|
|
{
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
return( -1 );
|
|
|
|
}
|
|
|
|
|
2017-08-23 10:55:41 +02:00
|
|
|
/*
|
|
|
|
* Reset (init or clear) a verify_chain
|
|
|
|
*/
|
|
|
|
static void x509_crt_verify_chain_reset(
|
|
|
|
mbedtls_x509_crt_verify_chain *ver_chain )
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
for( i = 0; i < MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE; i++ )
|
|
|
|
{
|
|
|
|
ver_chain->items[i].crt = NULL;
|
2019-01-10 10:19:26 +01:00
|
|
|
ver_chain->items[i].flags = (uint32_t) -1;
|
2017-08-23 10:55:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
ver_chain->len = 0;
|
|
|
|
}
|
|
|
|
|
2009-01-03 22:22:43 +01:00
|
|
|
/*
|
|
|
|
* Version ::= INTEGER { v1(0), v2(1), v3(2) }
|
|
|
|
*/
|
|
|
|
static int x509_get_version( unsigned char **p,
|
2010-03-16 22:09:09 +01:00
|
|
|
const unsigned char *end,
|
2009-01-03 22:22:43 +01:00
|
|
|
int *ver )
|
|
|
|
{
|
2011-04-24 10:57:21 +02:00
|
|
|
int ret;
|
|
|
|
size_t len;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
|
|
|
|
MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) != 0 )
|
2009-01-03 22:22:43 +01:00
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
|
2011-10-19 16:15:17 +02:00
|
|
|
{
|
|
|
|
*ver = 0;
|
|
|
|
return( 0 );
|
|
|
|
}
|
2009-01-03 22:22:43 +01:00
|
|
|
|
Always return a high-level error code from X.509 module
Some functions within the X.509 module return an ASN.1 low level
error code where instead this error code should be wrapped by a
high-level X.509 error code as in the bulk of the module.
Specifically, the following functions are affected:
- mbedtls_x509_get_ext()
- x509_get_version()
- x509_get_uid()
This commit modifies these functions to always return an
X.509 high level error code.
Care has to be taken when adapting `mbetls_x509_get_ext()`:
Currently, the callers `mbedtls_x509_crt_ext()` treat the
return code `MBEDTLS_ERR_ASN1_UNEXPECTED_TAG` specially to
gracefully detect and continue if the extension structure is not
present. Wrapping the ASN.1 error with
`MBEDTLS_ERR_X509_INVALID_EXTENSIONS` and adapting the check
accordingly would mean that an unexpected tag somewhere
down the extension parsing would be ignored by the caller.
The way out of this is the following: Luckily, the extension
structure is always the last field in the surrounding structure,
so if there is some data remaining, it must be an Extension
structure, so we don't need to deal with a tag mismatch gracefully
in the first place.
We may therefore wrap the return code from the initial call to
`mbedtls_asn1_get_tag()` in `mbedtls_x509_get_ext()` by
`MBEDTLS_ERR_X509_INVALID_EXTENSIONS` and simply remove
the special treatment of `MBEDTLS_ERR_ASN1_UNEXPECTED_TAG`
in the callers `x509_crl_get_ext()` and `x509_crt_get_ext()`.
This renders `mbedtls_x509_get_ext()` unsuitable if it ever
happened that an Extension structure is optional and does not
occur at the end of its surrounding structure, but for CRTs
and CRLs, it's fine.
The following tests need to be adapted:
- "TBSCertificate v3, issuerID wrong tag"
The issuerID is optional, so if we look for its presence
but find a different tag, we silently continue and try
parsing the subjectID, and then the extensions. The tag '00'
used in this test doesn't match either of these, and the
previous code would hence return LENGTH_MISMATCH after
unsucessfully trying issuerID, subjectID and Extensions.
With the new code, any data remaining after issuerID and
subjectID _must_ be Extension data, so we fail with
UNEXPECTED_TAG when trying to parse the Extension data.
- "TBSCertificate v3, UIDs, invalid length"
The test hardcodes the expectation of
MBEDTLS_ERR_ASN1_INVALID_LENGTH, which needs to be
wrapped in MBEDTLS_ERR_X509_INVALID_FORMAT now.
Fixes #2431.
2019-02-12 12:52:10 +01:00
|
|
|
return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
|
2009-01-03 22:22:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
end = *p + len;
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
|
|
|
|
return( MBEDTLS_ERR_X509_INVALID_VERSION + ret );
|
2009-01-03 22:22:43 +01:00
|
|
|
|
|
|
|
if( *p != end )
|
2015-04-08 12:49:31 +02:00
|
|
|
return( MBEDTLS_ERR_X509_INVALID_VERSION +
|
|
|
|
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
|
2009-01-03 22:22:43 +01:00
|
|
|
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
2019-06-25 10:39:21 +02:00
|
|
|
#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME)
|
2009-05-02 17:13:40 +02:00
|
|
|
/*
|
|
|
|
* Validity ::= SEQUENCE {
|
|
|
|
* notBefore Time,
|
|
|
|
* notAfter Time }
|
|
|
|
*/
|
|
|
|
static int x509_get_dates( unsigned char **p,
|
2010-03-16 22:09:09 +01:00
|
|
|
const unsigned char *end,
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_x509_time *from,
|
|
|
|
mbedtls_x509_time *to )
|
2009-05-02 17:13:40 +02:00
|
|
|
{
|
2011-04-24 10:57:21 +02:00
|
|
|
int ret;
|
|
|
|
size_t len;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
|
|
|
|
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
|
|
|
|
return( MBEDTLS_ERR_X509_INVALID_DATE + ret );
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2009-05-02 17:13:40 +02:00
|
|
|
end = *p + len;
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
if( ( ret = mbedtls_x509_get_time( p, end, from ) ) != 0 )
|
2009-05-02 17:13:40 +02:00
|
|
|
return( ret );
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
if( ( ret = mbedtls_x509_get_time( p, end, to ) ) != 0 )
|
2009-05-02 17:13:40 +02:00
|
|
|
return( ret );
|
2009-01-03 22:22:43 +01:00
|
|
|
|
|
|
|
if( *p != end )
|
2015-04-08 12:49:31 +02:00
|
|
|
return( MBEDTLS_ERR_X509_INVALID_DATE +
|
|
|
|
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
|
2009-01-03 22:22:43 +01:00
|
|
|
|
|
|
|
return( 0 );
|
|
|
|
}
|
2019-06-25 10:39:21 +02:00
|
|
|
#else /* !MBEDTLS_X509_CRT_REMOVE_TIME */
|
|
|
|
static int x509_skip_dates( unsigned char **p,
|
|
|
|
const unsigned char *end )
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
size_t len;
|
|
|
|
|
|
|
|
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
|
|
|
|
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
|
|
|
|
return( MBEDTLS_ERR_X509_INVALID_DATE + ret );
|
|
|
|
|
2019-07-30 14:11:25 +02:00
|
|
|
/* skip contents of the sequence */
|
|
|
|
*p += len;
|
2019-06-25 10:39:21 +02:00
|
|
|
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
#endif /* MBEDTLS_X509_CRT_REMOVE_TIME */
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2019-06-25 11:19:58 +02:00
|
|
|
#if !defined(MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID)
|
2009-01-03 22:22:43 +01:00
|
|
|
/*
|
|
|
|
* X.509 v2/v3 unique identifier (not parsed)
|
|
|
|
*/
|
|
|
|
static int x509_get_uid( unsigned char **p,
|
2010-03-16 22:09:09 +01:00
|
|
|
const unsigned char *end,
|
2019-06-07 13:04:39 +02:00
|
|
|
mbedtls_x509_buf_raw *uid, int n )
|
2009-01-03 22:22:43 +01:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if( *p == end )
|
|
|
|
return( 0 );
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
if( ( ret = mbedtls_asn1_get_tag( p, end, &uid->len,
|
|
|
|
MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | n ) ) != 0 )
|
2009-01-03 22:22:43 +01:00
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
|
2009-01-03 22:22:43 +01:00
|
|
|
return( 0 );
|
|
|
|
|
Always return a high-level error code from X.509 module
Some functions within the X.509 module return an ASN.1 low level
error code where instead this error code should be wrapped by a
high-level X.509 error code as in the bulk of the module.
Specifically, the following functions are affected:
- mbedtls_x509_get_ext()
- x509_get_version()
- x509_get_uid()
This commit modifies these functions to always return an
X.509 high level error code.
Care has to be taken when adapting `mbetls_x509_get_ext()`:
Currently, the callers `mbedtls_x509_crt_ext()` treat the
return code `MBEDTLS_ERR_ASN1_UNEXPECTED_TAG` specially to
gracefully detect and continue if the extension structure is not
present. Wrapping the ASN.1 error with
`MBEDTLS_ERR_X509_INVALID_EXTENSIONS` and adapting the check
accordingly would mean that an unexpected tag somewhere
down the extension parsing would be ignored by the caller.
The way out of this is the following: Luckily, the extension
structure is always the last field in the surrounding structure,
so if there is some data remaining, it must be an Extension
structure, so we don't need to deal with a tag mismatch gracefully
in the first place.
We may therefore wrap the return code from the initial call to
`mbedtls_asn1_get_tag()` in `mbedtls_x509_get_ext()` by
`MBEDTLS_ERR_X509_INVALID_EXTENSIONS` and simply remove
the special treatment of `MBEDTLS_ERR_ASN1_UNEXPECTED_TAG`
in the callers `x509_crl_get_ext()` and `x509_crt_get_ext()`.
This renders `mbedtls_x509_get_ext()` unsuitable if it ever
happened that an Extension structure is optional and does not
occur at the end of its surrounding structure, but for CRTs
and CRLs, it's fine.
The following tests need to be adapted:
- "TBSCertificate v3, issuerID wrong tag"
The issuerID is optional, so if we look for its presence
but find a different tag, we silently continue and try
parsing the subjectID, and then the extensions. The tag '00'
used in this test doesn't match either of these, and the
previous code would hence return LENGTH_MISMATCH after
unsucessfully trying issuerID, subjectID and Extensions.
With the new code, any data remaining after issuerID and
subjectID _must_ be Extension data, so we fail with
UNEXPECTED_TAG when trying to parse the Extension data.
- "TBSCertificate v3, UIDs, invalid length"
The test hardcodes the expectation of
MBEDTLS_ERR_ASN1_INVALID_LENGTH, which needs to be
wrapped in MBEDTLS_ERR_X509_INVALID_FORMAT now.
Fixes #2431.
2019-02-12 12:52:10 +01:00
|
|
|
return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
|
2009-01-03 22:22:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
uid->p = *p;
|
|
|
|
*p += uid->len;
|
|
|
|
|
|
|
|
return( 0 );
|
|
|
|
}
|
2019-06-25 11:19:58 +02:00
|
|
|
#else /* !MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID */
|
|
|
|
static int x509_skip_uid( unsigned char **p,
|
|
|
|
const unsigned char *end,
|
|
|
|
int n )
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
size_t len;
|
|
|
|
|
|
|
|
if( *p == end )
|
|
|
|
return( 0 );
|
|
|
|
|
|
|
|
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
|
|
|
|
MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | n ) ) != 0 )
|
|
|
|
{
|
|
|
|
if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
|
|
|
|
return( 0 );
|
|
|
|
|
|
|
|
return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
|
|
|
|
}
|
|
|
|
|
|
|
|
*p += len;
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
#endif /* MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID */
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2013-09-16 13:49:26 +02:00
|
|
|
static int x509_get_basic_constraints( unsigned char **p,
|
|
|
|
const unsigned char *end,
|
|
|
|
int *ca_istrue,
|
|
|
|
int *max_pathlen )
|
2009-01-03 22:22:43 +01:00
|
|
|
{
|
2011-04-24 10:57:21 +02:00
|
|
|
int ret;
|
|
|
|
size_t len;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
|
|
|
/*
|
2013-09-16 13:49:26 +02:00
|
|
|
* BasicConstraints ::= SEQUENCE {
|
|
|
|
* cA BOOLEAN DEFAULT FALSE,
|
|
|
|
* pathLenConstraint INTEGER (0..MAX) OPTIONAL }
|
2009-01-03 22:22:43 +01:00
|
|
|
*/
|
2013-09-16 13:49:26 +02:00
|
|
|
*ca_istrue = 0; /* DEFAULT FALSE */
|
|
|
|
*max_pathlen = 0; /* endless */
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
|
|
|
|
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
|
2019-02-22 12:09:48 +01:00
|
|
|
return( ret );
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2013-09-16 13:49:26 +02:00
|
|
|
if( *p == end )
|
2014-06-17 14:06:49 +02:00
|
|
|
return( 0 );
|
2009-05-02 17:13:40 +02:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
if( ( ret = mbedtls_asn1_get_bool( p, end, ca_istrue ) ) != 0 )
|
2009-05-02 17:13:40 +02:00
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
|
|
|
|
ret = mbedtls_asn1_get_int( p, end, ca_istrue );
|
2009-05-02 17:13:40 +02:00
|
|
|
|
2013-09-16 13:49:26 +02:00
|
|
|
if( ret != 0 )
|
2019-02-22 12:09:48 +01:00
|
|
|
return( ret );
|
2009-05-02 17:13:40 +02:00
|
|
|
|
2013-09-16 13:49:26 +02:00
|
|
|
if( *ca_istrue != 0 )
|
|
|
|
*ca_istrue = 1;
|
2009-05-02 17:13:40 +02:00
|
|
|
}
|
|
|
|
|
2013-09-16 13:49:26 +02:00
|
|
|
if( *p == end )
|
2014-06-17 14:06:49 +02:00
|
|
|
return( 0 );
|
2013-09-16 13:49:26 +02:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
if( ( ret = mbedtls_asn1_get_int( p, end, max_pathlen ) ) != 0 )
|
2019-02-22 12:09:48 +01:00
|
|
|
return( ret );
|
2013-09-16 13:49:26 +02:00
|
|
|
|
2009-05-02 17:13:40 +02:00
|
|
|
if( *p != end )
|
2019-02-22 12:09:48 +01:00
|
|
|
return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
|
2009-05-02 17:13:40 +02:00
|
|
|
|
2013-09-16 13:49:26 +02:00
|
|
|
(*max_pathlen)++;
|
|
|
|
|
2014-06-17 14:06:49 +02:00
|
|
|
return( 0 );
|
2009-05-02 17:13:40 +02:00
|
|
|
}
|
|
|
|
|
2013-09-16 13:49:26 +02:00
|
|
|
static int x509_get_ns_cert_type( unsigned char **p,
|
|
|
|
const unsigned char *end,
|
|
|
|
unsigned char *ns_cert_type)
|
2011-10-12 11:58:41 +02:00
|
|
|
{
|
|
|
|
int ret;
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_x509_bitstring bs = { 0, 0, NULL };
|
2011-10-12 11:58:41 +02:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 )
|
2019-02-22 12:09:48 +01:00
|
|
|
return( ret );
|
2011-10-12 11:58:41 +02:00
|
|
|
|
2013-09-16 13:49:26 +02:00
|
|
|
if( bs.len != 1 )
|
2019-02-22 12:09:48 +01:00
|
|
|
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
|
2011-01-15 17:57:55 +01:00
|
|
|
|
|
|
|
/* Get actual bitstring */
|
|
|
|
*ns_cert_type = *bs.p;
|
2014-06-17 14:06:49 +02:00
|
|
|
return( 0 );
|
2011-01-15 17:57:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static int x509_get_key_usage( unsigned char **p,
|
|
|
|
const unsigned char *end,
|
2019-05-13 13:52:57 +02:00
|
|
|
uint16_t *key_usage)
|
2011-01-15 17:57:55 +01:00
|
|
|
{
|
|
|
|
int ret;
|
2015-06-23 10:14:36 +02:00
|
|
|
size_t i;
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_x509_bitstring bs = { 0, 0, NULL };
|
2011-01-15 17:57:55 +01:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 )
|
2019-02-22 12:09:48 +01:00
|
|
|
return( ret );
|
2011-01-15 17:57:55 +01:00
|
|
|
|
2012-08-23 15:03:52 +02:00
|
|
|
if( bs.len < 1 )
|
2019-02-22 12:09:48 +01:00
|
|
|
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
|
2011-01-15 17:57:55 +01:00
|
|
|
|
|
|
|
/* Get actual bitstring */
|
2015-06-23 10:14:36 +02:00
|
|
|
*key_usage = 0;
|
2019-05-13 13:52:57 +02:00
|
|
|
for( i = 0; i < bs.len && i < sizeof( *key_usage ); i++ )
|
2015-06-23 10:14:36 +02:00
|
|
|
{
|
2019-05-13 13:52:57 +02:00
|
|
|
*key_usage |= (uint16_t) bs.p[i] << ( 8*i );
|
2015-06-23 10:14:36 +02:00
|
|
|
}
|
|
|
|
|
2014-06-17 14:06:49 +02:00
|
|
|
return( 0 );
|
2011-01-15 17:57:55 +01:00
|
|
|
}
|
|
|
|
|
2019-05-02 15:48:25 +02:00
|
|
|
static int asn1_build_sequence_cb( void *ctx,
|
|
|
|
int tag,
|
|
|
|
unsigned char *data,
|
|
|
|
size_t data_len )
|
2019-05-02 14:21:27 +02:00
|
|
|
{
|
|
|
|
mbedtls_asn1_sequence **cur_ptr = (mbedtls_asn1_sequence **) ctx;
|
|
|
|
mbedtls_asn1_sequence *cur = *cur_ptr;
|
|
|
|
|
|
|
|
/* Allocate and assign next pointer */
|
|
|
|
if( cur->buf.p != NULL )
|
|
|
|
{
|
|
|
|
cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) );
|
|
|
|
if( cur->next == NULL )
|
|
|
|
return( MBEDTLS_ERR_ASN1_ALLOC_FAILED );
|
|
|
|
cur = cur->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
cur->buf.tag = tag;
|
|
|
|
cur->buf.p = data;
|
|
|
|
cur->buf.len = data_len;
|
|
|
|
|
|
|
|
*cur_ptr = cur;
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
2019-05-02 15:48:25 +02:00
|
|
|
/*
|
|
|
|
* ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
|
|
|
|
*
|
|
|
|
* KeyPurposeId ::= OBJECT IDENTIFIER
|
|
|
|
*/
|
|
|
|
static int x509_get_ext_key_usage( unsigned char **p,
|
|
|
|
const unsigned char *end,
|
|
|
|
mbedtls_x509_sequence *ext_key_usage)
|
|
|
|
{
|
|
|
|
return( mbedtls_asn1_traverse_sequence_of( p, end,
|
|
|
|
0xFF, MBEDTLS_ASN1_OID,
|
|
|
|
0, 0,
|
|
|
|
asn1_build_sequence_cb,
|
2019-05-29 15:41:44 +02:00
|
|
|
(void *) &ext_key_usage ) );
|
2019-05-02 15:48:25 +02:00
|
|
|
}
|
|
|
|
|
2012-02-11 17:09:32 +01:00
|
|
|
/*
|
|
|
|
* SubjectAltName ::= GeneralNames
|
|
|
|
*
|
|
|
|
* GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
|
|
|
|
*
|
|
|
|
* GeneralName ::= CHOICE {
|
|
|
|
* otherName [0] OtherName,
|
|
|
|
* rfc822Name [1] IA5String,
|
|
|
|
* dNSName [2] IA5String,
|
|
|
|
* x400Address [3] ORAddress,
|
|
|
|
* directoryName [4] Name,
|
|
|
|
* ediPartyName [5] EDIPartyName,
|
|
|
|
* uniformResourceIdentifier [6] IA5String,
|
|
|
|
* iPAddress [7] OCTET STRING,
|
|
|
|
* registeredID [8] OBJECT IDENTIFIER }
|
|
|
|
*
|
|
|
|
* OtherName ::= SEQUENCE {
|
|
|
|
* type-id OBJECT IDENTIFIER,
|
|
|
|
* value [0] EXPLICIT ANY DEFINED BY type-id }
|
|
|
|
*
|
|
|
|
* EDIPartyName ::= SEQUENCE {
|
|
|
|
* nameAssigner [0] DirectoryString OPTIONAL,
|
|
|
|
* partyName [1] DirectoryString }
|
|
|
|
*
|
2015-01-22 17:11:05 +01:00
|
|
|
* NOTE: we only parse and use dNSName at this point.
|
2012-02-11 17:09:32 +01:00
|
|
|
*/
|
2019-02-21 15:46:54 +01:00
|
|
|
static int x509_get_subject_alt_name( unsigned char *p,
|
2012-02-11 17:09:32 +01:00
|
|
|
const unsigned char *end,
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_x509_sequence *subject_alt_name )
|
2012-02-11 17:09:32 +01:00
|
|
|
{
|
2019-02-22 12:09:48 +01:00
|
|
|
return( mbedtls_asn1_traverse_sequence_of( &p, end,
|
|
|
|
MBEDTLS_ASN1_TAG_CLASS_MASK,
|
|
|
|
MBEDTLS_ASN1_CONTEXT_SPECIFIC,
|
|
|
|
MBEDTLS_ASN1_TAG_VALUE_MASK,
|
|
|
|
2 /* SubjectAlt DNS */,
|
2019-05-02 15:48:25 +02:00
|
|
|
asn1_build_sequence_cb,
|
2019-05-29 15:41:44 +02:00
|
|
|
(void *) &subject_alt_name ) );
|
2012-02-11 17:09:32 +01:00
|
|
|
}
|
|
|
|
|
2011-01-15 17:57:55 +01:00
|
|
|
/*
|
|
|
|
* X.509 v3 extensions
|
|
|
|
*
|
2009-05-02 17:13:40 +02:00
|
|
|
*/
|
2019-02-22 12:09:48 +01:00
|
|
|
static int x509_crt_get_ext_cb( void *ctx,
|
|
|
|
int tag,
|
|
|
|
unsigned char *p,
|
|
|
|
size_t ext_len )
|
2009-05-02 17:13:40 +02:00
|
|
|
{
|
2011-04-24 10:57:21 +02:00
|
|
|
int ret;
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
mbedtls_x509_crt_frame *frame = (mbedtls_x509_crt_frame *) ctx;
|
2011-04-24 10:57:21 +02:00
|
|
|
size_t len;
|
2019-02-22 12:09:48 +01:00
|
|
|
unsigned char *end, *end_ext_octet;
|
|
|
|
mbedtls_x509_buf extn_oid = { 0, 0, NULL };
|
|
|
|
int is_critical = 0; /* DEFAULT FALSE */
|
|
|
|
int ext_type = 0;
|
2009-05-02 17:13:40 +02:00
|
|
|
|
2019-02-22 12:09:48 +01:00
|
|
|
((void) tag);
|
2009-05-02 17:13:40 +02:00
|
|
|
|
2019-02-22 12:09:48 +01:00
|
|
|
/*
|
|
|
|
* Extension ::= SEQUENCE {
|
|
|
|
* extnID OBJECT IDENTIFIER,
|
|
|
|
* critical BOOLEAN DEFAULT FALSE,
|
|
|
|
* extnValue OCTET STRING }
|
|
|
|
*/
|
2009-05-02 17:13:40 +02:00
|
|
|
|
2019-02-22 12:09:48 +01:00
|
|
|
end = p + ext_len;
|
2013-04-07 22:00:46 +02:00
|
|
|
|
2019-02-22 12:09:48 +01:00
|
|
|
/* Get extension ID */
|
|
|
|
if( ( ret = mbedtls_asn1_get_tag( &p, end, &extn_oid.len,
|
|
|
|
MBEDTLS_ASN1_OID ) ) != 0 )
|
|
|
|
goto err;
|
2013-04-07 22:00:46 +02:00
|
|
|
|
2019-02-22 12:09:48 +01:00
|
|
|
extn_oid.tag = MBEDTLS_ASN1_OID;
|
|
|
|
extn_oid.p = p;
|
|
|
|
p += extn_oid.len;
|
|
|
|
|
|
|
|
/* Get optional critical */
|
|
|
|
if( ( ret = mbedtls_asn1_get_bool( &p, end, &is_critical ) ) != 0 &&
|
|
|
|
( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) )
|
|
|
|
goto err;
|
2013-04-07 22:00:46 +02:00
|
|
|
|
2019-02-22 12:09:48 +01:00
|
|
|
/* Data should be octet string type */
|
|
|
|
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
|
|
|
|
MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
|
|
|
|
goto err;
|
2014-11-12 17:47:28 +01:00
|
|
|
|
2019-02-22 12:09:48 +01:00
|
|
|
end_ext_octet = p + len;
|
|
|
|
if( end_ext_octet != end )
|
|
|
|
{
|
|
|
|
ret = MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
|
|
|
|
goto err;
|
|
|
|
}
|
2013-04-07 22:00:46 +02:00
|
|
|
|
2019-02-22 12:09:48 +01:00
|
|
|
/*
|
|
|
|
* Detect supported extensions
|
|
|
|
*/
|
|
|
|
ret = mbedtls_oid_get_x509_ext_type( &extn_oid, &ext_type );
|
|
|
|
if( ret != 0 )
|
|
|
|
{
|
|
|
|
#if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
|
|
|
|
if( is_critical )
|
2013-04-07 22:00:46 +02:00
|
|
|
{
|
2019-02-22 12:09:48 +01:00
|
|
|
/* Data is marked as critical: fail */
|
|
|
|
ret = MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
|
|
|
|
goto err;
|
|
|
|
}
|
2019-05-29 15:43:17 +02:00
|
|
|
#endif /* MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION */
|
2019-02-22 12:09:48 +01:00
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Forbid repeated extensions */
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
if( ( frame->ext_types & ext_type ) != 0 )
|
2019-02-22 12:09:48 +01:00
|
|
|
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS );
|
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
frame->ext_types |= ext_type;
|
2019-02-22 12:09:48 +01:00
|
|
|
switch( ext_type )
|
|
|
|
{
|
2015-04-20 13:19:02 +02:00
|
|
|
case MBEDTLS_X509_EXT_BASIC_CONSTRAINTS:
|
2019-02-22 12:09:48 +01:00
|
|
|
{
|
|
|
|
int ca_istrue;
|
|
|
|
int max_pathlen;
|
|
|
|
|
2011-01-15 17:57:55 +01:00
|
|
|
/* Parse basic constraints */
|
2019-02-22 12:09:48 +01:00
|
|
|
ret = x509_get_basic_constraints( &p, end_ext_octet,
|
|
|
|
&ca_istrue,
|
|
|
|
&max_pathlen );
|
|
|
|
if( ret != 0 )
|
|
|
|
goto err;
|
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
frame->ca_istrue = ca_istrue;
|
|
|
|
frame->max_pathlen = max_pathlen;
|
2013-04-07 22:00:46 +02:00
|
|
|
break;
|
2019-02-22 12:09:48 +01:00
|
|
|
}
|
2013-04-07 22:00:46 +02:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
case MBEDTLS_X509_EXT_KEY_USAGE:
|
2011-01-15 17:57:55 +01:00
|
|
|
/* Parse key usage */
|
2019-02-22 12:09:48 +01:00
|
|
|
ret = x509_get_key_usage( &p, end_ext_octet,
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
&frame->key_usage );
|
2019-02-22 12:09:48 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
goto err;
|
2013-04-07 22:00:46 +02:00
|
|
|
break;
|
|
|
|
|
2019-02-22 12:09:48 +01:00
|
|
|
case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME:
|
|
|
|
/* Copy reference to raw subject alt name data. */
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
frame->subject_alt_raw.p = p;
|
|
|
|
frame->subject_alt_raw.len = end_ext_octet - p;
|
|
|
|
|
|
|
|
ret = mbedtls_asn1_traverse_sequence_of( &p, end_ext_octet,
|
|
|
|
MBEDTLS_ASN1_TAG_CLASS_MASK,
|
|
|
|
MBEDTLS_ASN1_CONTEXT_SPECIFIC,
|
|
|
|
MBEDTLS_ASN1_TAG_VALUE_MASK,
|
|
|
|
2 /* SubjectAlt DNS */,
|
|
|
|
NULL, NULL );
|
|
|
|
if( ret != 0 )
|
|
|
|
goto err;
|
2013-04-07 22:00:46 +02:00
|
|
|
break;
|
|
|
|
|
2019-02-22 12:09:48 +01:00
|
|
|
case MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE:
|
|
|
|
/* Parse extended key usage */
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
frame->ext_key_usage_raw.p = p;
|
|
|
|
frame->ext_key_usage_raw.len = end_ext_octet - p;
|
|
|
|
if( frame->ext_key_usage_raw.len == 0 )
|
2019-02-21 15:46:54 +01:00
|
|
|
{
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
ret = MBEDTLS_ERR_ASN1_INVALID_LENGTH;
|
|
|
|
goto err;
|
2019-02-21 15:46:54 +01:00
|
|
|
}
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
|
|
|
|
/* Check structural sanity of extension. */
|
|
|
|
ret = mbedtls_asn1_traverse_sequence_of( &p, end_ext_octet,
|
|
|
|
0xFF, MBEDTLS_ASN1_OID,
|
|
|
|
0, 0, NULL, NULL );
|
|
|
|
if( ret != 0 )
|
|
|
|
goto err;
|
|
|
|
|
2013-04-07 22:00:46 +02:00
|
|
|
break;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
case MBEDTLS_X509_EXT_NS_CERT_TYPE:
|
2013-04-07 22:00:46 +02:00
|
|
|
/* Parse netscape certificate type */
|
2019-02-22 12:09:48 +01:00
|
|
|
ret = x509_get_ns_cert_type( &p, end_ext_octet,
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
&frame->ns_cert_type );
|
2019-02-22 12:09:48 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
goto err;
|
2013-04-07 22:00:46 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2019-02-22 12:09:48 +01:00
|
|
|
/*
|
|
|
|
* If this is a non-critical extension, which the oid layer
|
|
|
|
* supports, but there isn't an X.509 parser for it,
|
|
|
|
* skip the extension.
|
|
|
|
*/
|
|
|
|
#if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
|
|
|
|
if( is_critical )
|
|
|
|
return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
|
|
|
|
#endif
|
|
|
|
p = end_ext_octet;
|
2009-01-03 22:22:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return( 0 );
|
2019-02-22 12:09:48 +01:00
|
|
|
|
|
|
|
err:
|
|
|
|
return( ret );
|
|
|
|
}
|
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
static int x509_crt_frame_parse_ext( mbedtls_x509_crt_frame *frame )
|
2019-02-22 12:09:48 +01:00
|
|
|
{
|
|
|
|
int ret;
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
unsigned char *p = frame->v3_ext.p;
|
|
|
|
unsigned char *end = p + frame->v3_ext.len;
|
2019-02-22 12:09:48 +01:00
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
if( p == end )
|
2019-02-22 12:09:48 +01:00
|
|
|
return( 0 );
|
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
ret = mbedtls_asn1_traverse_sequence_of( &p, end,
|
2019-02-22 12:09:48 +01:00
|
|
|
0xFF, MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED,
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
0, 0, x509_crt_get_ext_cb, frame );
|
2019-02-22 12:09:48 +01:00
|
|
|
|
|
|
|
if( ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE )
|
|
|
|
return( ret );
|
|
|
|
if( ret == MBEDTLS_ERR_X509_INVALID_EXTENSIONS )
|
|
|
|
return( ret );
|
|
|
|
|
|
|
|
if( ret != 0 )
|
|
|
|
ret += MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
|
|
|
|
|
|
|
|
return( ret );
|
2009-01-03 22:22:43 +01:00
|
|
|
}
|
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
static int x509_crt_parse_frame( unsigned char *start,
|
|
|
|
unsigned char *end,
|
|
|
|
mbedtls_x509_crt_frame *frame )
|
2009-01-03 22:22:43 +01:00
|
|
|
{
|
2011-04-24 10:57:21 +02:00
|
|
|
int ret;
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
unsigned char *p;
|
2011-05-26 15:16:06 +02:00
|
|
|
size_t len;
|
2014-01-22 10:12:57 +01:00
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
mbedtls_x509_buf tmp;
|
|
|
|
unsigned char *tbs_start;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
mbedtls_x509_buf outer_sig_alg;
|
|
|
|
size_t inner_sig_alg_len;
|
|
|
|
unsigned char *inner_sig_alg_start;
|
2009-03-28 19:52:39 +01:00
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
memset( frame, 0, sizeof( *frame ) );
|
2009-01-03 22:22:43 +01:00
|
|
|
|
|
|
|
/*
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
* Certificate ::= SEQUENCE {
|
2009-01-03 22:22:43 +01:00
|
|
|
* tbsCertificate TBSCertificate,
|
|
|
|
* signatureAlgorithm AlgorithmIdentifier,
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
* signatureValue BIT STRING
|
|
|
|
* }
|
|
|
|
*
|
2009-01-03 22:22:43 +01:00
|
|
|
*/
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
p = start;
|
|
|
|
|
|
|
|
frame->raw.p = p;
|
2015-04-08 12:49:31 +02:00
|
|
|
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
|
|
|
|
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
|
2009-01-03 22:22:43 +01:00
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
return( MBEDTLS_ERR_X509_INVALID_FORMAT );
|
2009-01-03 22:22:43 +01:00
|
|
|
}
|
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
/* NOTE: We are currently not checking that the `Certificate`
|
|
|
|
* structure spans the entire buffer. */
|
|
|
|
end = p + len;
|
|
|
|
frame->raw.len = end - frame->raw.p;
|
2016-02-17 15:34:12 +01:00
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
/*
|
|
|
|
* TBSCertificate ::= SEQUENCE { ...
|
|
|
|
*/
|
|
|
|
frame->tbs.p = p;
|
|
|
|
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
|
|
|
|
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
|
2019-01-31 09:57:44 +01:00
|
|
|
{
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
return( ret + MBEDTLS_ERR_X509_INVALID_FORMAT );
|
2019-01-31 09:57:44 +01:00
|
|
|
}
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
tbs_start = p;
|
|
|
|
|
|
|
|
/* Breadth-first parsing: Jump over TBS for now. */
|
|
|
|
p += len;
|
|
|
|
frame->tbs.len = p - frame->tbs.p;
|
2016-02-17 15:34:12 +01:00
|
|
|
|
2009-01-03 22:22:43 +01:00
|
|
|
/*
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
* AlgorithmIdentifier ::= SEQUENCE { ...
|
2009-01-03 22:22:43 +01:00
|
|
|
*/
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
outer_sig_alg.p = p;
|
2015-04-08 12:49:31 +02:00
|
|
|
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
|
|
|
|
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
|
2009-01-03 22:22:43 +01:00
|
|
|
{
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
|
2009-01-03 22:22:43 +01:00
|
|
|
}
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
p += len;
|
|
|
|
outer_sig_alg.len = p - outer_sig_alg.p;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
|
|
|
/*
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
* signatureValue BIT STRING
|
2009-01-03 22:22:43 +01:00
|
|
|
*/
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
ret = mbedtls_x509_get_sig( &p, end, &tmp );
|
|
|
|
if( ret != 0 )
|
2009-01-03 22:22:43 +01:00
|
|
|
return( ret );
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
frame->sig.p = tmp.p;
|
|
|
|
frame->sig.len = tmp.len;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
/* Check that we consumed the entire `Certificate` structure. */
|
|
|
|
if( p != end )
|
2009-01-03 22:22:43 +01:00
|
|
|
{
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
return( MBEDTLS_ERR_X509_INVALID_FORMAT +
|
|
|
|
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
|
2009-01-03 22:22:43 +01:00
|
|
|
}
|
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
/* Parse TBSCertificate structure
|
|
|
|
*
|
|
|
|
* TBSCertificate ::= SEQUENCE {
|
|
|
|
* version [0] EXPLICIT Version DEFAULT v1,
|
|
|
|
* serialNumber CertificateSerialNumber,
|
|
|
|
* signature AlgorithmIdentifier,
|
|
|
|
* issuer Name,
|
|
|
|
* validity Validity,
|
|
|
|
* subject Name,
|
|
|
|
* subjectPublicKeyInfo SubjectPublicKeyInfo,
|
|
|
|
* issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
|
|
|
|
* -- If present, version MUST be v2 or v3
|
|
|
|
* subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
|
|
|
|
* -- If present, version MUST be v2 or v3
|
|
|
|
* extensions [3] EXPLICIT Extensions OPTIONAL
|
|
|
|
* -- If present, version MUST be v3
|
|
|
|
* }
|
|
|
|
*/
|
|
|
|
end = frame->tbs.p + frame->tbs.len;
|
|
|
|
p = tbs_start;
|
2017-03-09 17:16:11 +01:00
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
/*
|
|
|
|
* Version ::= INTEGER { v1(0), v2(1), v3(2) }
|
|
|
|
*/
|
2009-01-03 22:22:43 +01:00
|
|
|
{
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
int version;
|
|
|
|
ret = x509_get_version( &p, end, &version );
|
|
|
|
if( ret != 0 )
|
|
|
|
return( ret );
|
|
|
|
|
|
|
|
if( version < 0 || version > 2 )
|
|
|
|
return( MBEDTLS_ERR_X509_UNKNOWN_VERSION );
|
|
|
|
|
|
|
|
frame->version = version + 1;
|
2009-01-03 22:22:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
* CertificateSerialNumber ::= INTEGER
|
2009-01-03 22:22:43 +01:00
|
|
|
*/
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
ret = mbedtls_x509_get_serial( &p, end, &tmp );
|
|
|
|
if( ret != 0 )
|
|
|
|
return( ret );
|
2009-01-03 22:22:43 +01:00
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
frame->serial.p = tmp.p;
|
|
|
|
frame->serial.len = tmp.len;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
/*
|
|
|
|
* signature AlgorithmIdentifier
|
|
|
|
*/
|
|
|
|
inner_sig_alg_start = p;
|
|
|
|
ret = mbedtls_x509_get_sig_alg_raw( &p, end, &frame->sig_md,
|
|
|
|
&frame->sig_pk, NULL );
|
|
|
|
if( ret != 0 )
|
2009-01-03 22:22:43 +01:00
|
|
|
return( ret );
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
inner_sig_alg_len = p - inner_sig_alg_start;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
frame->sig_alg.p = inner_sig_alg_start;
|
|
|
|
frame->sig_alg.len = inner_sig_alg_len;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
/* Consistency check:
|
|
|
|
* Inner and outer AlgorithmIdentifier structures must coincide:
|
2009-01-03 22:22:43 +01:00
|
|
|
*
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
* Quoting RFC 5280, Section 4.1.1.2:
|
|
|
|
* This field MUST contain the same algorithm identifier as the
|
|
|
|
* signature field in the sequence tbsCertificate (Section 4.1.2.3).
|
2009-01-03 22:22:43 +01:00
|
|
|
*/
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
if( outer_sig_alg.len != inner_sig_alg_len ||
|
|
|
|
memcmp( outer_sig_alg.p, inner_sig_alg_start, inner_sig_alg_len ) != 0 )
|
2009-01-03 22:22:43 +01:00
|
|
|
{
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
return( MBEDTLS_ERR_X509_SIG_MISMATCH );
|
2009-01-03 22:22:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
* issuer Name
|
|
|
|
*
|
|
|
|
* Name ::= CHOICE { -- only one possibility for now --
|
|
|
|
* rdnSequence RDNSequence }
|
|
|
|
*
|
|
|
|
* RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
|
2009-01-03 22:22:43 +01:00
|
|
|
*/
|
2019-03-04 15:43:43 +01:00
|
|
|
frame->issuer_raw.p = p;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
ret = mbedtls_asn1_get_tag( &p, end, &len,
|
|
|
|
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE );
|
|
|
|
if( ret != 0 )
|
|
|
|
return( ret + MBEDTLS_ERR_X509_INVALID_FORMAT );
|
|
|
|
p += len;
|
2019-03-04 15:43:43 +01:00
|
|
|
frame->issuer_raw.len = p - frame->issuer_raw.p;
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
|
2019-07-02 17:47:40 +02:00
|
|
|
/* Comparing the raw buffer to itself amounts to structural validation. */
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
ret = mbedtls_x509_name_cmp_raw( &frame->issuer_raw,
|
|
|
|
&frame->issuer_raw,
|
|
|
|
NULL, NULL );
|
|
|
|
if( ret != 0 )
|
|
|
|
return( ret );
|
2009-01-03 22:22:43 +01:00
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
/*
|
|
|
|
* Validity ::= SEQUENCE { ...
|
|
|
|
*/
|
2019-06-25 10:39:21 +02:00
|
|
|
#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME)
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
ret = x509_get_dates( &p, end, &frame->valid_from, &frame->valid_to );
|
|
|
|
if( ret != 0 )
|
|
|
|
return( ret );
|
2019-06-25 10:39:21 +02:00
|
|
|
#else /* !MBEDTLS_X509_CRT_REMOVE_TIME */
|
|
|
|
ret = x509_skip_dates( &p, end );
|
|
|
|
if( ret != 0 )
|
|
|
|
return( ret );
|
|
|
|
#endif /* MBEDTLS_X509_CRT_REMOVE_TIME */
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* subject Name
|
|
|
|
*
|
|
|
|
* Name ::= CHOICE { -- only one possibility for now --
|
|
|
|
* rdnSequence RDNSequence }
|
|
|
|
*
|
|
|
|
* RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
|
|
|
|
*/
|
2019-03-04 15:43:43 +01:00
|
|
|
frame->subject_raw.p = p;
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
|
|
|
|
ret = mbedtls_asn1_get_tag( &p, end, &len,
|
|
|
|
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE );
|
|
|
|
if( ret != 0 )
|
|
|
|
return( ret + MBEDTLS_ERR_X509_INVALID_FORMAT );
|
|
|
|
p += len;
|
2019-03-04 15:43:43 +01:00
|
|
|
frame->subject_raw.len = p - frame->subject_raw.p;
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
|
2019-07-02 17:47:40 +02:00
|
|
|
/* Comparing the raw buffer to itself amounts to structural validation. */
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
ret = mbedtls_x509_name_cmp_raw( &frame->subject_raw,
|
|
|
|
&frame->subject_raw,
|
|
|
|
NULL, NULL );
|
|
|
|
if( ret != 0 )
|
2009-01-03 22:22:43 +01:00
|
|
|
return( ret );
|
|
|
|
|
|
|
|
/*
|
2013-07-09 12:13:24 +02:00
|
|
|
* SubjectPublicKeyInfo
|
2009-01-03 22:22:43 +01:00
|
|
|
*/
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
frame->pubkey_raw.p = p;
|
|
|
|
ret = mbedtls_asn1_get_tag( &p, end, &len,
|
|
|
|
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE );
|
|
|
|
if( ret != 0 )
|
|
|
|
return( ret + MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
|
|
|
|
p += len;
|
|
|
|
frame->pubkey_raw.len = p - frame->pubkey_raw.p;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2019-06-08 08:38:20 +02:00
|
|
|
if( frame->version != 1 )
|
2009-01-03 22:22:43 +01:00
|
|
|
{
|
2019-06-25 11:19:58 +02:00
|
|
|
#if !defined(MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID)
|
2019-06-07 12:47:12 +02:00
|
|
|
/*
|
|
|
|
* issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
|
|
|
|
* -- If present, version shall be v2 or v3
|
|
|
|
*/
|
2019-06-07 13:04:39 +02:00
|
|
|
ret = x509_get_uid( &p, end, &frame->issuer_id, 1 /* implicit tag */ );
|
2009-01-03 22:22:43 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
return( ret );
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
|
2019-06-07 12:47:12 +02:00
|
|
|
/*
|
|
|
|
* subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
|
|
|
|
* -- If present, version shall be v2 or v3
|
|
|
|
*/
|
2019-06-07 13:04:39 +02:00
|
|
|
ret = x509_get_uid( &p, end, &frame->subject_id, 2 /* implicit tag */ );
|
2009-01-03 22:22:43 +01:00
|
|
|
if( ret != 0 )
|
2013-09-16 13:49:26 +02:00
|
|
|
return( ret );
|
2019-06-25 11:19:58 +02:00
|
|
|
#else /* !MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID */
|
|
|
|
ret = x509_skip_uid( &p, end, 1 /* implicit tag */ );
|
|
|
|
if( ret != 0 )
|
|
|
|
return( ret );
|
|
|
|
ret = x509_skip_uid( &p, end, 2 /* implicit tag */ );
|
|
|
|
if( ret != 0 )
|
|
|
|
return( ret );
|
|
|
|
#endif /* MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID */
|
2009-05-02 17:13:40 +02:00
|
|
|
}
|
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
/*
|
|
|
|
* extensions [3] EXPLICIT Extensions OPTIONAL
|
|
|
|
* -- If present, version shall be v3
|
|
|
|
*/
|
2015-04-08 12:49:31 +02:00
|
|
|
#if !defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3)
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
if( frame->version == 3 )
|
2013-09-23 15:01:36 +02:00
|
|
|
#endif
|
2015-03-27 16:15:55 +01:00
|
|
|
{
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
if( p != end )
|
2009-05-02 17:13:40 +02:00
|
|
|
{
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
ret = mbedtls_asn1_get_tag( &p, end, &len,
|
|
|
|
MBEDTLS_ASN1_CONTEXT_SPECIFIC |
|
|
|
|
MBEDTLS_ASN1_CONSTRUCTED | 3 );
|
|
|
|
if( len == 0 )
|
|
|
|
ret = MBEDTLS_ERR_ASN1_OUT_OF_DATA;
|
|
|
|
if( ret != 0 )
|
|
|
|
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
|
|
|
|
|
|
|
|
frame->v3_ext.p = p;
|
|
|
|
frame->v3_ext.len = len;
|
|
|
|
|
|
|
|
p += len;
|
2009-05-02 17:13:40 +02:00
|
|
|
}
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
|
|
|
|
ret = x509_crt_frame_parse_ext( frame );
|
|
|
|
if( ret != 0 )
|
|
|
|
return( ret );
|
2009-05-02 17:13:40 +02:00
|
|
|
}
|
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
/* Wrapup: Check that we consumed the entire `TBSCertificate` structure. */
|
2009-05-02 17:13:40 +02:00
|
|
|
if( p != end )
|
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
return( MBEDTLS_ERR_X509_INVALID_FORMAT +
|
|
|
|
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
|
2009-05-02 17:13:40 +02:00
|
|
|
}
|
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
return( 0 );
|
|
|
|
}
|
2009-05-02 17:13:40 +02:00
|
|
|
|
2019-05-13 14:53:21 +02:00
|
|
|
static int x509_crt_subject_from_frame( mbedtls_x509_crt_frame const *frame,
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
mbedtls_x509_name *subject )
|
|
|
|
{
|
2019-03-04 15:43:43 +01:00
|
|
|
return( mbedtls_x509_get_name( frame->subject_raw.p,
|
|
|
|
frame->subject_raw.len,
|
|
|
|
subject ) );
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
}
|
|
|
|
|
2019-05-13 14:53:21 +02:00
|
|
|
static int x509_crt_issuer_from_frame( mbedtls_x509_crt_frame const *frame,
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
mbedtls_x509_name *issuer )
|
|
|
|
{
|
2019-03-04 15:43:43 +01:00
|
|
|
return( mbedtls_x509_get_name( frame->issuer_raw.p,
|
|
|
|
frame->issuer_raw.len,
|
|
|
|
issuer ) );
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
}
|
|
|
|
|
2019-05-13 14:53:21 +02:00
|
|
|
static int x509_crt_subject_alt_from_frame( mbedtls_x509_crt_frame const *frame,
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
mbedtls_x509_sequence *subject_alt )
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
unsigned char *p = frame->subject_alt_raw.p;
|
|
|
|
unsigned char *end = p + frame->subject_alt_raw.len;
|
|
|
|
|
|
|
|
memset( subject_alt, 0, sizeof( *subject_alt ) );
|
|
|
|
|
|
|
|
if( ( frame->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME ) == 0 )
|
|
|
|
return( 0 );
|
|
|
|
|
|
|
|
ret = x509_get_subject_alt_name( p, end, subject_alt );
|
|
|
|
if( ret != 0 )
|
|
|
|
ret += MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
|
|
|
|
return( ret );
|
|
|
|
}
|
|
|
|
|
2019-05-13 14:53:21 +02:00
|
|
|
static int x509_crt_ext_key_usage_from_frame( mbedtls_x509_crt_frame const *frame,
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
mbedtls_x509_sequence *ext_key_usage )
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
unsigned char *p = frame->ext_key_usage_raw.p;
|
|
|
|
unsigned char *end = p + frame->ext_key_usage_raw.len;
|
|
|
|
|
|
|
|
memset( ext_key_usage, 0, sizeof( *ext_key_usage ) );
|
|
|
|
|
|
|
|
if( ( frame->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) == 0 )
|
|
|
|
return( 0 );
|
|
|
|
|
|
|
|
ret = x509_get_ext_key_usage( &p, end, ext_key_usage );
|
|
|
|
if( ret != 0 )
|
2009-05-02 17:13:40 +02:00
|
|
|
{
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
ret += MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
|
2009-05-02 17:13:40 +02:00
|
|
|
return( ret );
|
|
|
|
}
|
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
2019-02-28 14:23:38 +01:00
|
|
|
#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING)
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
static int x509_crt_pk_from_frame( mbedtls_x509_crt_frame *frame,
|
|
|
|
mbedtls_pk_context *pk )
|
|
|
|
{
|
|
|
|
unsigned char *p = frame->pubkey_raw.p;
|
|
|
|
unsigned char *end = p + frame->pubkey_raw.len;
|
|
|
|
return( mbedtls_pk_parse_subpubkey( &p, end, pk ) );
|
|
|
|
}
|
2019-02-28 14:23:38 +01:00
|
|
|
#endif /* !MBEDTLS_X509_ON_DEMAND_PARSING */
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Parse and fill a single X.509 certificate in DER format
|
|
|
|
*/
|
|
|
|
static int x509_crt_parse_der_core( mbedtls_x509_crt *crt,
|
|
|
|
const unsigned char *buf,
|
|
|
|
size_t buflen,
|
|
|
|
int make_copy )
|
|
|
|
{
|
|
|
|
int ret;
|
2019-02-25 14:50:14 +01:00
|
|
|
mbedtls_x509_crt_frame *frame;
|
|
|
|
mbedtls_x509_crt_cache *cache;
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
|
|
|
|
if( crt == NULL || buf == NULL )
|
|
|
|
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
|
|
|
|
|
|
|
|
if( make_copy == 0 )
|
2009-05-02 17:13:40 +02:00
|
|
|
{
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
crt->raw.p = (unsigned char*) buf;
|
|
|
|
crt->raw.len = buflen;
|
|
|
|
crt->own_buffer = 0;
|
2009-05-02 17:13:40 +02:00
|
|
|
}
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
else
|
2009-05-02 17:13:40 +02:00
|
|
|
{
|
2019-05-03 13:37:12 +02:00
|
|
|
/* Call mbedtls_calloc with buflen + 1 in order to avoid potential
|
|
|
|
* return of NULL in case of length 0 certificates, which we want
|
|
|
|
* to cleanly fail with MBEDTLS_ERR_X509_INVALID_FORMAT in the
|
|
|
|
* core parsing routine, but not here. */
|
|
|
|
crt->raw.p = mbedtls_calloc( 1, buflen + 1 );
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
if( crt->raw.p == NULL )
|
|
|
|
return( MBEDTLS_ERR_X509_ALLOC_FAILED );
|
|
|
|
crt->raw.len = buflen;
|
|
|
|
memcpy( crt->raw.p, buf, buflen );
|
|
|
|
|
|
|
|
crt->own_buffer = 1;
|
2009-05-02 17:13:40 +02:00
|
|
|
}
|
|
|
|
|
2019-02-25 14:50:14 +01:00
|
|
|
cache = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt_cache ) );
|
|
|
|
if( cache == NULL )
|
|
|
|
{
|
|
|
|
ret = MBEDTLS_ERR_X509_ALLOC_FAILED;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
crt->cache = cache;
|
|
|
|
x509_crt_cache_init( cache );
|
|
|
|
|
2019-03-04 12:52:23 +01:00
|
|
|
#if defined(MBEDTLS_X509_ON_DEMAND_PARSING)
|
|
|
|
|
2019-02-25 14:50:14 +01:00
|
|
|
ret = mbedtls_x509_crt_cache_provide_frame( crt );
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
goto exit;
|
|
|
|
|
2019-03-05 16:29:23 +01:00
|
|
|
frame = crt->cache->frame;
|
2019-02-25 14:50:14 +01:00
|
|
|
|
2019-03-04 12:52:23 +01:00
|
|
|
#else /* MBEDTLS_X509_ON_DEMAND_PARSING */
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
|
2019-03-04 12:52:23 +01:00
|
|
|
frame = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt_frame ) );
|
|
|
|
if( frame == NULL )
|
|
|
|
{
|
|
|
|
ret = MBEDTLS_ERR_X509_ALLOC_FAILED;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
cache->frame = frame;
|
|
|
|
|
|
|
|
ret = x509_crt_parse_frame( crt->raw.p,
|
|
|
|
crt->raw.p + crt->raw.len,
|
|
|
|
frame );
|
|
|
|
if( ret != 0 )
|
|
|
|
goto exit;
|
2019-02-25 14:50:14 +01:00
|
|
|
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
/* Copy frame to legacy CRT structure -- that's inefficient, but if
|
|
|
|
* memory matters, the new CRT structure should be used anyway. */
|
2019-03-04 16:13:45 +01:00
|
|
|
x509_buf_raw_to_buf( &crt->tbs, &frame->tbs );
|
|
|
|
x509_buf_raw_to_buf( &crt->serial, &frame->serial );
|
|
|
|
x509_buf_raw_to_buf( &crt->issuer_raw, &frame->issuer_raw );
|
|
|
|
x509_buf_raw_to_buf( &crt->subject_raw, &frame->subject_raw );
|
2019-06-25 11:19:58 +02:00
|
|
|
#if !defined(MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID)
|
2019-03-04 16:13:45 +01:00
|
|
|
x509_buf_raw_to_buf( &crt->issuer_id, &frame->issuer_id );
|
|
|
|
x509_buf_raw_to_buf( &crt->subject_id, &frame->subject_id );
|
2019-06-25 11:19:58 +02:00
|
|
|
#endif /* !MBEDTLS_X509_CRT_REMOVE_SUBJECT_ISSUER_ID */
|
2019-03-04 16:13:45 +01:00
|
|
|
x509_buf_raw_to_buf( &crt->pk_raw, &frame->pubkey_raw );
|
|
|
|
x509_buf_raw_to_buf( &crt->sig, &frame->sig );
|
|
|
|
x509_buf_raw_to_buf( &crt->v3_ext, &frame->v3_ext );
|
2019-06-25 10:39:21 +02:00
|
|
|
|
|
|
|
#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME)
|
2019-02-25 14:50:14 +01:00
|
|
|
crt->valid_from = frame->valid_from;
|
|
|
|
crt->valid_to = frame->valid_to;
|
2019-06-25 10:39:21 +02:00
|
|
|
#endif /* !MBEDTLS_X509_CRT_REMOVE_TIME */
|
|
|
|
|
2019-02-25 14:50:14 +01:00
|
|
|
crt->version = frame->version;
|
|
|
|
crt->ca_istrue = frame->ca_istrue;
|
|
|
|
crt->max_pathlen = frame->max_pathlen;
|
|
|
|
crt->ext_types = frame->ext_types;
|
|
|
|
crt->key_usage = frame->key_usage;
|
|
|
|
crt->ns_cert_type = frame->ns_cert_type;
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Obtain the remaining fields from the frame.
|
|
|
|
*/
|
|
|
|
|
2009-05-02 17:13:40 +02:00
|
|
|
{
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
/* sig_oid: Previously, needed for convenience in
|
|
|
|
* mbedtls_x509_crt_info(), now pure legacy burden. */
|
2019-02-25 14:50:14 +01:00
|
|
|
unsigned char *tmp = frame->sig_alg.p;
|
|
|
|
unsigned char *end = tmp + frame->sig_alg.len;
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
mbedtls_x509_buf sig_oid, sig_params;
|
|
|
|
|
|
|
|
ret = mbedtls_x509_get_alg( &tmp, end,
|
|
|
|
&sig_oid, &sig_params );
|
|
|
|
if( ret != 0 )
|
|
|
|
{
|
|
|
|
/* This should never happen, because we check
|
|
|
|
* the sanity of the AlgorithmIdentifier structure
|
|
|
|
* during frame parsing. */
|
|
|
|
ret = MBEDTLS_ERR_X509_FATAL_ERROR;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
crt->sig_oid = sig_oid;
|
|
|
|
|
|
|
|
/* Signature parameters */
|
2019-02-25 14:50:14 +01:00
|
|
|
tmp = frame->sig_alg.p;
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
ret = mbedtls_x509_get_sig_alg_raw( &tmp, end,
|
|
|
|
&crt->sig_md, &crt->sig_pk,
|
|
|
|
&crt->sig_opts );
|
|
|
|
if( ret != 0 )
|
|
|
|
{
|
|
|
|
/* Again, this should never happen. */
|
|
|
|
ret = MBEDTLS_ERR_X509_FATAL_ERROR;
|
|
|
|
goto exit;
|
|
|
|
}
|
2009-05-02 17:13:40 +02:00
|
|
|
}
|
|
|
|
|
2019-02-25 14:50:14 +01:00
|
|
|
ret = x509_crt_pk_from_frame( frame, &crt->pk );
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
goto exit;
|
|
|
|
|
2019-02-25 14:50:14 +01:00
|
|
|
ret = x509_crt_subject_from_frame( frame, &crt->subject );
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
goto exit;
|
|
|
|
|
2019-02-25 14:50:14 +01:00
|
|
|
ret = x509_crt_issuer_from_frame( frame, &crt->issuer );
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
goto exit;
|
|
|
|
|
2019-02-25 14:50:14 +01:00
|
|
|
ret = x509_crt_subject_alt_from_frame( frame, &crt->subject_alt_names );
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
goto exit;
|
|
|
|
|
2019-02-25 14:50:14 +01:00
|
|
|
ret = x509_crt_ext_key_usage_from_frame( frame, &crt->ext_key_usage );
|
|
|
|
if( ret != 0 )
|
|
|
|
goto exit;
|
2019-02-28 14:23:38 +01:00
|
|
|
#endif /* !MBEDTLS_X509_ON_DEMAND_PARSING */
|
2019-02-25 14:50:14 +01:00
|
|
|
|
2019-03-04 12:52:23 +01:00
|
|
|
/* Currently, we accept DER encoded CRTs with trailing garbage
|
|
|
|
* and promise to not account for the garbage in the `raw` field.
|
|
|
|
*
|
|
|
|
* Note that this means that `crt->raw.len` is not necessarily the
|
|
|
|
* full size of the heap buffer allocated at `crt->raw.p` in case
|
|
|
|
* of copy-mode, but this is not a problem: freeing the buffer doesn't
|
|
|
|
* need the size, and the garbage data doesn't need zeroization. */
|
|
|
|
crt->raw.len = frame->raw.len;
|
|
|
|
|
|
|
|
cache->pk_raw = frame->pubkey_raw;
|
|
|
|
|
2019-02-27 14:12:24 +01:00
|
|
|
/* Free the frame before parsing the public key to
|
|
|
|
* keep peak RAM usage low. This is slightly inefficient
|
|
|
|
* because the frame will need to be parsed again on the
|
|
|
|
* first usage of the CRT, but that seems acceptable.
|
|
|
|
* As soon as the frame gets used multiple times, it
|
|
|
|
* will be cached by default. */
|
|
|
|
x509_crt_cache_clear_frame( crt->cache );
|
|
|
|
|
2019-02-25 14:50:14 +01:00
|
|
|
/* The cache just references the PK structure from the legacy
|
|
|
|
* implementation, so set up the latter first before setting up
|
2019-02-27 14:12:24 +01:00
|
|
|
* the cache.
|
|
|
|
*
|
|
|
|
* We're not actually using the parsed PK context here;
|
|
|
|
* we just parse it to check that it's well-formed. */
|
2019-02-25 14:50:14 +01:00
|
|
|
ret = mbedtls_x509_crt_cache_provide_pk( crt );
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
goto exit;
|
2019-02-27 14:12:24 +01:00
|
|
|
x509_crt_cache_clear_pk( crt->cache );
|
Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:
First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).
Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.
Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.
Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.
These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-02-15 16:27:59 +01:00
|
|
|
|
|
|
|
exit:
|
|
|
|
if( ret != 0 )
|
|
|
|
mbedtls_x509_crt_free( crt );
|
|
|
|
|
|
|
|
return( ret );
|
2013-09-16 13:49:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Parse one X.509 certificate in DER format from a buffer and add them to a
|
|
|
|
* chained list
|
|
|
|
*/
|
2019-01-31 09:57:44 +01:00
|
|
|
static int mbedtls_x509_crt_parse_der_internal( mbedtls_x509_crt *chain,
|
|
|
|
const unsigned char *buf,
|
|
|
|
size_t buflen,
|
|
|
|
int make_copy )
|
2013-09-16 13:49:26 +02:00
|
|
|
{
|
|
|
|
int ret;
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_x509_crt *crt = chain, *prev = NULL;
|
2013-09-16 13:49:26 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Check for valid input
|
|
|
|
*/
|
|
|
|
if( crt == NULL || buf == NULL )
|
2015-04-08 12:49:31 +02:00
|
|
|
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
|
2013-09-16 13:49:26 +02:00
|
|
|
|
2019-02-25 19:08:59 +01:00
|
|
|
while( crt->raw.p != NULL && crt->next != NULL )
|
2013-09-16 13:49:26 +02:00
|
|
|
{
|
|
|
|
prev = crt;
|
|
|
|
crt = crt->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Add new certificate on the end of the chain if needed.
|
|
|
|
*/
|
2019-02-25 19:08:59 +01:00
|
|
|
if( crt->raw.p != NULL && crt->next == NULL )
|
2009-05-02 17:13:40 +02:00
|
|
|
{
|
2015-05-26 16:04:06 +02:00
|
|
|
crt->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
|
2009-05-02 17:13:40 +02:00
|
|
|
|
2013-09-16 13:49:26 +02:00
|
|
|
if( crt->next == NULL )
|
2015-05-28 09:33:39 +02:00
|
|
|
return( MBEDTLS_ERR_X509_ALLOC_FAILED );
|
2009-05-02 17:13:40 +02:00
|
|
|
|
2013-09-16 13:49:26 +02:00
|
|
|
prev = crt;
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_x509_crt_init( crt->next );
|
2013-09-16 13:49:26 +02:00
|
|
|
crt = crt->next;
|
|
|
|
}
|
|
|
|
|
2019-01-31 09:57:44 +01:00
|
|
|
if( ( ret = x509_crt_parse_der_core( crt, buf, buflen, make_copy ) ) != 0 )
|
2013-09-16 13:49:26 +02:00
|
|
|
{
|
|
|
|
if( prev )
|
|
|
|
prev->next = NULL;
|
|
|
|
|
|
|
|
if( crt != chain )
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_free( crt );
|
2009-05-02 17:13:40 +02:00
|
|
|
|
2013-09-16 13:49:26 +02:00
|
|
|
return( ret );
|
2009-05-02 17:13:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
2019-01-31 09:57:44 +01:00
|
|
|
int mbedtls_x509_crt_parse_der_nocopy( mbedtls_x509_crt *chain,
|
|
|
|
const unsigned char *buf,
|
|
|
|
size_t buflen )
|
|
|
|
{
|
|
|
|
return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, 0 ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain,
|
|
|
|
const unsigned char *buf,
|
|
|
|
size_t buflen )
|
|
|
|
{
|
|
|
|
return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, 1 ) );
|
|
|
|
}
|
|
|
|
|
2009-04-19 20:44:26 +02:00
|
|
|
/*
|
2014-05-01 14:18:25 +02:00
|
|
|
* Parse one or more PEM certificates from a buffer and add them to the chained
|
|
|
|
* list
|
2009-04-19 20:44:26 +02:00
|
|
|
*/
|
2019-01-31 09:57:44 +01:00
|
|
|
int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain,
|
|
|
|
const unsigned char *buf,
|
|
|
|
size_t buflen )
|
2009-04-19 20:44:26 +02:00
|
|
|
{
|
2016-05-31 15:03:54 +02:00
|
|
|
#if defined(MBEDTLS_PEM_PARSE_C)
|
2016-12-07 16:05:53 +01:00
|
|
|
int success = 0, first_error = 0, total_failed = 0;
|
2015-04-08 12:49:31 +02:00
|
|
|
int buf_format = MBEDTLS_X509_FORMAT_DER;
|
2016-05-31 15:03:54 +02:00
|
|
|
#endif
|
2009-04-19 20:44:26 +02:00
|
|
|
|
2013-09-16 13:49:26 +02:00
|
|
|
/*
|
|
|
|
* Check for valid input
|
|
|
|
*/
|
|
|
|
if( chain == NULL || buf == NULL )
|
2015-04-08 12:49:31 +02:00
|
|
|
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
|
2009-04-19 20:44:26 +02:00
|
|
|
|
2013-09-16 13:49:26 +02:00
|
|
|
/*
|
|
|
|
* Determine buffer content. Buffer contains either one DER certificate or
|
|
|
|
* one or more PEM certificates.
|
|
|
|
*/
|
2015-04-08 12:49:31 +02:00
|
|
|
#if defined(MBEDTLS_PEM_PARSE_C)
|
2015-05-12 12:43:54 +02:00
|
|
|
if( buflen != 0 && buf[buflen - 1] == '\0' &&
|
2015-05-12 11:20:10 +02:00
|
|
|
strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
|
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
buf_format = MBEDTLS_X509_FORMAT_PEM;
|
2015-05-12 11:20:10 +02:00
|
|
|
}
|
2009-04-19 20:44:26 +02:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
if( buf_format == MBEDTLS_X509_FORMAT_DER )
|
|
|
|
return mbedtls_x509_crt_parse_der( chain, buf, buflen );
|
2016-05-31 15:03:54 +02:00
|
|
|
#else
|
|
|
|
return mbedtls_x509_crt_parse_der( chain, buf, buflen );
|
|
|
|
#endif
|
2013-08-19 14:29:31 +02:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
#if defined(MBEDTLS_PEM_PARSE_C)
|
|
|
|
if( buf_format == MBEDTLS_X509_FORMAT_PEM )
|
2013-05-14 13:26:51 +02:00
|
|
|
{
|
2013-09-16 13:49:26 +02:00
|
|
|
int ret;
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_pem_context pem;
|
2009-04-19 20:44:26 +02:00
|
|
|
|
2015-05-12 11:20:10 +02:00
|
|
|
/* 1 rather than 0 since the terminating NULL byte is counted in */
|
|
|
|
while( buflen > 1 )
|
2013-09-16 13:49:26 +02:00
|
|
|
{
|
|
|
|
size_t use_len;
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_pem_init( &pem );
|
2013-09-16 13:49:26 +02:00
|
|
|
|
2015-05-12 11:20:10 +02:00
|
|
|
/* If we get there, we know the string is null-terminated */
|
2015-04-08 12:49:31 +02:00
|
|
|
ret = mbedtls_pem_read_buffer( &pem,
|
2013-09-16 13:49:26 +02:00
|
|
|
"-----BEGIN CERTIFICATE-----",
|
|
|
|
"-----END CERTIFICATE-----",
|
|
|
|
buf, NULL, 0, &use_len );
|
|
|
|
|
|
|
|
if( ret == 0 )
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Was PEM encoded
|
|
|
|
*/
|
|
|
|
buflen -= use_len;
|
|
|
|
buf += use_len;
|
|
|
|
}
|
2015-04-08 12:49:31 +02:00
|
|
|
else if( ret == MBEDTLS_ERR_PEM_BAD_INPUT_DATA )
|
2013-09-16 13:49:26 +02:00
|
|
|
{
|
|
|
|
return( ret );
|
|
|
|
}
|
2015-04-08 12:49:31 +02:00
|
|
|
else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
|
2013-09-16 13:49:26 +02:00
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_pem_free( &pem );
|
2009-04-19 20:44:26 +02:00
|
|
|
|
2013-09-16 13:49:26 +02:00
|
|
|
/*
|
|
|
|
* PEM header and footer were found
|
|
|
|
*/
|
|
|
|
buflen -= use_len;
|
|
|
|
buf += use_len;
|
2009-04-19 20:44:26 +02:00
|
|
|
|
2013-09-16 13:49:26 +02:00
|
|
|
if( first_error == 0 )
|
|
|
|
first_error = ret;
|
2009-04-19 20:44:26 +02:00
|
|
|
|
2014-09-26 14:53:04 +02:00
|
|
|
total_failed++;
|
2013-09-16 13:49:26 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
ret = mbedtls_x509_crt_parse_der( chain, pem.buf, pem.buflen );
|
2013-09-16 13:49:26 +02:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_pem_free( &pem );
|
2013-09-16 13:49:26 +02:00
|
|
|
|
|
|
|
if( ret != 0 )
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Quit parsing on a memory error
|
|
|
|
*/
|
2015-05-28 09:33:39 +02:00
|
|
|
if( ret == MBEDTLS_ERR_X509_ALLOC_FAILED )
|
2013-09-16 13:49:26 +02:00
|
|
|
return( ret );
|
|
|
|
|
|
|
|
if( first_error == 0 )
|
|
|
|
first_error = ret;
|
|
|
|
|
|
|
|
total_failed++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
success = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( success )
|
|
|
|
return( total_failed );
|
|
|
|
else if( first_error )
|
|
|
|
return( first_error );
|
|
|
|
else
|
2015-04-08 12:49:31 +02:00
|
|
|
return( MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT );
|
2016-05-31 15:03:54 +02:00
|
|
|
#endif /* MBEDTLS_PEM_PARSE_C */
|
2009-04-19 20:44:26 +02:00
|
|
|
}
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
#if defined(MBEDTLS_FS_IO)
|
2009-01-03 22:22:43 +01:00
|
|
|
/*
|
|
|
|
* Load one or more certificates and add them to the chained list
|
|
|
|
*/
|
2015-04-08 12:49:31 +02:00
|
|
|
int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path )
|
2009-01-03 22:22:43 +01:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
size_t n;
|
|
|
|
unsigned char *buf;
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
|
2011-12-10 22:55:01 +01:00
|
|
|
return( ret );
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
ret = mbedtls_x509_crt_parse( chain, buf, n );
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2018-04-17 16:51:09 +02:00
|
|
|
mbedtls_platform_zeroize( buf, n );
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_free( buf );
|
2009-01-03 22:22:43 +01:00
|
|
|
|
|
|
|
return( ret );
|
|
|
|
}
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path )
|
2012-06-04 14:46:42 +02:00
|
|
|
{
|
|
|
|
int ret = 0;
|
2013-10-28 18:48:30 +01:00
|
|
|
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
|
2012-10-01 23:13:10 +02:00
|
|
|
int w_ret;
|
|
|
|
WCHAR szDir[MAX_PATH];
|
|
|
|
char filename[MAX_PATH];
|
2014-05-01 13:03:14 +02:00
|
|
|
char *p;
|
2015-10-21 10:16:29 +02:00
|
|
|
size_t len = strlen( path );
|
2012-10-01 23:13:10 +02:00
|
|
|
|
2014-05-01 13:03:14 +02:00
|
|
|
WIN32_FIND_DATAW file_data;
|
2012-06-04 14:46:42 +02:00
|
|
|
HANDLE hFind;
|
2012-11-02 12:06:08 +01:00
|
|
|
|
|
|
|
if( len > MAX_PATH - 3 )
|
2015-04-08 12:49:31 +02:00
|
|
|
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
|
2012-06-04 14:46:42 +02:00
|
|
|
|
2014-05-01 13:03:14 +02:00
|
|
|
memset( szDir, 0, sizeof(szDir) );
|
|
|
|
memset( filename, 0, MAX_PATH );
|
|
|
|
memcpy( filename, path, len );
|
|
|
|
filename[len++] = '\\';
|
|
|
|
p = filename + len;
|
2012-11-02 12:06:08 +01:00
|
|
|
filename[len++] = '*';
|
2012-10-01 23:13:10 +02:00
|
|
|
|
2016-11-03 02:11:37 +01:00
|
|
|
w_ret = MultiByteToWideChar( CP_ACP, 0, filename, (int)len, szDir,
|
2014-05-01 14:18:25 +02:00
|
|
|
MAX_PATH - 3 );
|
2015-01-23 18:50:34 +01:00
|
|
|
if( w_ret == 0 )
|
2015-04-08 12:49:31 +02:00
|
|
|
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
|
2012-06-04 14:46:42 +02:00
|
|
|
|
2012-11-02 13:53:26 +01:00
|
|
|
hFind = FindFirstFileW( szDir, &file_data );
|
2014-06-17 16:39:18 +02:00
|
|
|
if( hFind == INVALID_HANDLE_VALUE )
|
2015-04-08 12:49:31 +02:00
|
|
|
return( MBEDTLS_ERR_X509_FILE_IO_ERROR );
|
2012-06-04 14:46:42 +02:00
|
|
|
|
2012-11-02 12:06:08 +01:00
|
|
|
len = MAX_PATH - len;
|
2012-06-04 14:46:42 +02:00
|
|
|
do
|
|
|
|
{
|
2014-05-01 13:03:14 +02:00
|
|
|
memset( p, 0, len );
|
2012-10-01 23:13:10 +02:00
|
|
|
|
2012-06-04 23:29:15 +02:00
|
|
|
if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
|
2012-06-04 14:46:42 +02:00
|
|
|
continue;
|
|
|
|
|
2014-05-01 13:03:14 +02:00
|
|
|
w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
|
2014-06-17 16:39:18 +02:00
|
|
|
lstrlenW( file_data.cFileName ),
|
2015-10-21 10:16:29 +02:00
|
|
|
p, (int) len - 1,
|
2014-05-01 13:03:14 +02:00
|
|
|
NULL, NULL );
|
2015-01-23 18:50:34 +01:00
|
|
|
if( w_ret == 0 )
|
2017-01-09 14:09:16 +01:00
|
|
|
{
|
|
|
|
ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2012-06-04 14:46:42 +02:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
w_ret = mbedtls_x509_crt_parse_file( chain, filename );
|
2012-10-01 23:13:10 +02:00
|
|
|
if( w_ret < 0 )
|
2013-06-24 19:22:42 +02:00
|
|
|
ret++;
|
|
|
|
else
|
|
|
|
ret += w_ret;
|
2012-06-04 14:46:42 +02:00
|
|
|
}
|
2012-11-02 13:53:26 +01:00
|
|
|
while( FindNextFileW( hFind, &file_data ) != 0 );
|
2012-06-04 14:46:42 +02:00
|
|
|
|
2014-06-17 16:39:18 +02:00
|
|
|
if( GetLastError() != ERROR_NO_MORE_FILES )
|
2015-04-08 12:49:31 +02:00
|
|
|
ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
|
2012-06-04 14:46:42 +02:00
|
|
|
|
2017-01-09 14:09:16 +01:00
|
|
|
cleanup:
|
2012-06-04 14:46:42 +02:00
|
|
|
FindClose( hFind );
|
2013-10-14 15:51:50 +02:00
|
|
|
#else /* _WIN32 */
|
2013-11-26 16:47:11 +01:00
|
|
|
int t_ret;
|
2016-09-02 15:06:04 +02:00
|
|
|
int snp_ret;
|
2013-06-24 19:22:42 +02:00
|
|
|
struct stat sb;
|
2013-11-26 16:47:11 +01:00
|
|
|
struct dirent *entry;
|
2016-09-02 15:06:04 +02:00
|
|
|
char entry_name[MBEDTLS_X509_MAX_FILE_PATH_LEN];
|
2012-06-04 14:46:42 +02:00
|
|
|
DIR *dir = opendir( path );
|
|
|
|
|
2014-06-17 16:39:18 +02:00
|
|
|
if( dir == NULL )
|
2015-04-08 12:49:31 +02:00
|
|
|
return( MBEDTLS_ERR_X509_FILE_IO_ERROR );
|
2012-06-04 14:46:42 +02:00
|
|
|
|
2017-01-09 18:27:59 +01:00
|
|
|
#if defined(MBEDTLS_THREADING_C)
|
2015-05-27 20:07:18 +02:00
|
|
|
if( ( ret = mbedtls_mutex_lock( &mbedtls_threading_readdir_mutex ) ) != 0 )
|
2015-06-22 18:39:57 +02:00
|
|
|
{
|
|
|
|
closedir( dir );
|
2013-11-28 17:11:54 +01:00
|
|
|
return( ret );
|
2015-06-22 18:39:57 +02:00
|
|
|
}
|
2017-01-09 18:27:59 +01:00
|
|
|
#endif /* MBEDTLS_THREADING_C */
|
2013-11-28 17:11:54 +01:00
|
|
|
|
2013-11-26 16:47:11 +01:00
|
|
|
while( ( entry = readdir( dir ) ) != NULL )
|
2012-06-04 14:46:42 +02:00
|
|
|
{
|
2016-09-02 15:06:04 +02:00
|
|
|
snp_ret = mbedtls_snprintf( entry_name, sizeof entry_name,
|
|
|
|
"%s/%s", path, entry->d_name );
|
2013-06-24 19:22:42 +02:00
|
|
|
|
2016-09-02 15:06:04 +02:00
|
|
|
if( snp_ret < 0 || (size_t)snp_ret >= sizeof entry_name )
|
|
|
|
{
|
|
|
|
ret = MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
else if( stat( entry_name, &sb ) == -1 )
|
2013-09-09 17:26:14 +02:00
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
|
2013-11-28 17:11:54 +01:00
|
|
|
goto cleanup;
|
2013-09-09 17:26:14 +02:00
|
|
|
}
|
2013-06-24 19:22:42 +02:00
|
|
|
|
|
|
|
if( !S_ISREG( sb.st_mode ) )
|
2012-06-04 14:46:42 +02:00
|
|
|
continue;
|
|
|
|
|
2013-06-24 19:22:42 +02:00
|
|
|
// Ignore parse errors
|
|
|
|
//
|
2015-04-08 12:49:31 +02:00
|
|
|
t_ret = mbedtls_x509_crt_parse_file( chain, entry_name );
|
2012-06-04 14:46:42 +02:00
|
|
|
if( t_ret < 0 )
|
2013-06-24 19:22:42 +02:00
|
|
|
ret++;
|
2013-09-16 13:49:26 +02:00
|
|
|
else
|
|
|
|
ret += t_ret;
|
|
|
|
}
|
2013-11-28 17:11:54 +01:00
|
|
|
|
|
|
|
cleanup:
|
2016-09-02 15:06:04 +02:00
|
|
|
closedir( dir );
|
|
|
|
|
2017-01-09 18:27:59 +01:00
|
|
|
#if defined(MBEDTLS_THREADING_C)
|
2015-05-27 20:07:18 +02:00
|
|
|
if( mbedtls_mutex_unlock( &mbedtls_threading_readdir_mutex ) != 0 )
|
2015-04-08 12:49:31 +02:00
|
|
|
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
|
2017-01-09 18:27:59 +01:00
|
|
|
#endif /* MBEDTLS_THREADING_C */
|
2013-11-28 17:11:54 +01:00
|
|
|
|
2013-10-14 15:51:50 +02:00
|
|
|
#endif /* _WIN32 */
|
2013-08-14 13:39:57 +02:00
|
|
|
|
|
|
|
return( ret );
|
2013-07-11 16:17:23 +02:00
|
|
|
}
|
2015-04-08 12:49:31 +02:00
|
|
|
#endif /* MBEDTLS_FS_IO */
|
2013-07-11 16:17:23 +02:00
|
|
|
|
2019-06-25 10:42:57 +02:00
|
|
|
typedef struct mbedtls_x509_crt_sig_info
|
|
|
|
{
|
|
|
|
mbedtls_md_type_t sig_md;
|
|
|
|
mbedtls_pk_type_t sig_pk;
|
|
|
|
void *sig_opts;
|
|
|
|
uint8_t crt_hash[MBEDTLS_MD_MAX_SIZE];
|
|
|
|
size_t crt_hash_len;
|
|
|
|
mbedtls_x509_buf_raw sig;
|
|
|
|
mbedtls_x509_buf_raw issuer_raw;
|
|
|
|
} mbedtls_x509_crt_sig_info;
|
|
|
|
|
|
|
|
static void x509_crt_free_sig_info( mbedtls_x509_crt_sig_info *info )
|
|
|
|
{
|
|
|
|
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
|
|
|
|
mbedtls_free( info->sig_opts );
|
|
|
|
#else
|
|
|
|
((void) info);
|
|
|
|
#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
|
|
|
|
}
|
|
|
|
|
|
|
|
static int x509_crt_get_sig_info( mbedtls_x509_crt_frame const *frame,
|
|
|
|
mbedtls_x509_crt_sig_info *info )
|
|
|
|
{
|
|
|
|
const mbedtls_md_info_t *md_info;
|
|
|
|
|
|
|
|
md_info = mbedtls_md_info_from_type( frame->sig_md );
|
|
|
|
if( mbedtls_md( md_info, frame->tbs.p, frame->tbs.len,
|
|
|
|
info->crt_hash ) != 0 )
|
|
|
|
{
|
|
|
|
/* Note: this can't happen except after an internal error */
|
|
|
|
return( -1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
info->crt_hash_len = mbedtls_md_get_size( md_info );
|
|
|
|
|
|
|
|
/* Make sure that this function leaves the target structure
|
|
|
|
* ready to be freed, regardless of success of failure. */
|
|
|
|
info->sig_opts = NULL;
|
|
|
|
|
|
|
|
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
unsigned char *alg_start = frame->sig_alg.p;
|
|
|
|
unsigned char *alg_end = alg_start + frame->sig_alg.len;
|
|
|
|
|
|
|
|
/* Get signature options -- currently only
|
|
|
|
* necessary for RSASSA-PSS. */
|
|
|
|
ret = mbedtls_x509_get_sig_alg_raw( &alg_start, alg_end, &info->sig_md,
|
|
|
|
&info->sig_pk, &info->sig_opts );
|
|
|
|
if( ret != 0 )
|
|
|
|
{
|
|
|
|
/* Note: this can't happen except after an internal error */
|
|
|
|
return( -1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
|
|
|
|
info->sig_md = frame->sig_md;
|
|
|
|
info->sig_pk = frame->sig_pk;
|
|
|
|
#endif /* !MBEDTLS_X509_RSASSA_PSS_SUPPORT */
|
|
|
|
|
|
|
|
info->issuer_raw = frame->issuer_raw;
|
|
|
|
info->sig = frame->sig;
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
2019-06-10 16:08:43 +02:00
|
|
|
#if !defined(MBEDTLS_X509_REMOVE_INFO)
|
2014-04-01 13:43:28 +02:00
|
|
|
static int x509_info_subject_alt_name( char **buf, size_t *size,
|
2015-04-08 12:49:31 +02:00
|
|
|
const mbedtls_x509_sequence *subject_alt_name )
|
2014-04-01 13:43:28 +02:00
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
size_t n = *size;
|
|
|
|
char *p = *buf;
|
2015-04-08 12:49:31 +02:00
|
|
|
const mbedtls_x509_sequence *cur = subject_alt_name;
|
2014-04-01 18:00:07 +02:00
|
|
|
const char *sep = "";
|
|
|
|
size_t sep_len = 0;
|
2014-04-01 13:43:28 +02:00
|
|
|
|
|
|
|
while( cur != NULL )
|
|
|
|
{
|
2014-04-01 18:00:07 +02:00
|
|
|
if( cur->buf.len + sep_len >= n )
|
2014-04-01 13:43:28 +02:00
|
|
|
{
|
|
|
|
*p = '\0';
|
2015-06-22 11:12:02 +02:00
|
|
|
return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
|
2014-04-01 13:43:28 +02:00
|
|
|
}
|
|
|
|
|
2014-04-01 18:00:07 +02:00
|
|
|
n -= cur->buf.len + sep_len;
|
|
|
|
for( i = 0; i < sep_len; i++ )
|
|
|
|
*p++ = sep[i];
|
2014-04-01 13:43:28 +02:00
|
|
|
for( i = 0; i < cur->buf.len; i++ )
|
|
|
|
*p++ = cur->buf.p[i];
|
|
|
|
|
2014-04-01 18:00:07 +02:00
|
|
|
sep = ", ";
|
|
|
|
sep_len = 2;
|
|
|
|
|
2014-04-01 13:43:28 +02:00
|
|
|
cur = cur->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
*p = '\0';
|
|
|
|
|
|
|
|
*size = n;
|
|
|
|
*buf = p;
|
|
|
|
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
2014-04-01 18:12:24 +02:00
|
|
|
#define PRINT_ITEM(i) \
|
|
|
|
{ \
|
2015-04-08 12:49:31 +02:00
|
|
|
ret = mbedtls_snprintf( p, n, "%s" i, sep ); \
|
2015-06-22 11:12:02 +02:00
|
|
|
MBEDTLS_X509_SAFE_SNPRINTF; \
|
2014-04-01 18:12:24 +02:00
|
|
|
sep = ", "; \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define CERT_TYPE(type,name) \
|
2018-10-15 13:01:35 +02:00
|
|
|
if( ns_cert_type & (type) ) \
|
2014-04-01 18:12:24 +02:00
|
|
|
PRINT_ITEM( name );
|
|
|
|
|
2014-04-01 13:01:11 +02:00
|
|
|
static int x509_info_cert_type( char **buf, size_t *size,
|
|
|
|
unsigned char ns_cert_type )
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
size_t n = *size;
|
|
|
|
char *p = *buf;
|
2014-04-01 18:00:07 +02:00
|
|
|
const char *sep = "";
|
2014-04-01 13:01:11 +02:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT, "SSL Client" );
|
2015-04-20 13:19:02 +02:00
|
|
|
CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER, "SSL Server" );
|
2015-04-08 12:49:31 +02:00
|
|
|
CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL, "Email" );
|
|
|
|
CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING, "Object Signing" );
|
|
|
|
CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_RESERVED, "Reserved" );
|
2015-04-20 13:19:02 +02:00
|
|
|
CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CA, "SSL CA" );
|
|
|
|
CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA, "Email CA" );
|
|
|
|
CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA, "Object Signing CA" );
|
2014-04-01 13:01:11 +02:00
|
|
|
|
|
|
|
*size = n;
|
|
|
|
*buf = p;
|
|
|
|
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
2014-04-01 18:12:24 +02:00
|
|
|
#define KEY_USAGE(code,name) \
|
2018-10-15 13:01:35 +02:00
|
|
|
if( key_usage & (code) ) \
|
2014-04-01 18:12:24 +02:00
|
|
|
PRINT_ITEM( name );
|
|
|
|
|
2014-04-01 14:12:11 +02:00
|
|
|
static int x509_info_key_usage( char **buf, size_t *size,
|
2015-06-23 10:14:36 +02:00
|
|
|
unsigned int key_usage )
|
2014-04-01 14:12:11 +02:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
size_t n = *size;
|
|
|
|
char *p = *buf;
|
2014-04-01 18:00:07 +02:00
|
|
|
const char *sep = "";
|
2014-04-01 14:12:11 +02:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
KEY_USAGE( MBEDTLS_X509_KU_DIGITAL_SIGNATURE, "Digital Signature" );
|
|
|
|
KEY_USAGE( MBEDTLS_X509_KU_NON_REPUDIATION, "Non Repudiation" );
|
2015-04-20 13:19:02 +02:00
|
|
|
KEY_USAGE( MBEDTLS_X509_KU_KEY_ENCIPHERMENT, "Key Encipherment" );
|
|
|
|
KEY_USAGE( MBEDTLS_X509_KU_DATA_ENCIPHERMENT, "Data Encipherment" );
|
|
|
|
KEY_USAGE( MBEDTLS_X509_KU_KEY_AGREEMENT, "Key Agreement" );
|
2015-04-08 12:49:31 +02:00
|
|
|
KEY_USAGE( MBEDTLS_X509_KU_KEY_CERT_SIGN, "Key Cert Sign" );
|
|
|
|
KEY_USAGE( MBEDTLS_X509_KU_CRL_SIGN, "CRL Sign" );
|
2015-06-23 10:14:36 +02:00
|
|
|
KEY_USAGE( MBEDTLS_X509_KU_ENCIPHER_ONLY, "Encipher Only" );
|
|
|
|
KEY_USAGE( MBEDTLS_X509_KU_DECIPHER_ONLY, "Decipher Only" );
|
2014-04-01 14:12:11 +02:00
|
|
|
|
|
|
|
*size = n;
|
|
|
|
*buf = p;
|
|
|
|
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
2014-04-01 17:32:44 +02:00
|
|
|
static int x509_info_ext_key_usage( char **buf, size_t *size,
|
2015-04-08 12:49:31 +02:00
|
|
|
const mbedtls_x509_sequence *extended_key_usage )
|
2014-04-01 17:32:44 +02:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
const char *desc;
|
|
|
|
size_t n = *size;
|
|
|
|
char *p = *buf;
|
2015-04-08 12:49:31 +02:00
|
|
|
const mbedtls_x509_sequence *cur = extended_key_usage;
|
2014-04-01 18:00:07 +02:00
|
|
|
const char *sep = "";
|
2014-04-01 17:32:44 +02:00
|
|
|
|
|
|
|
while( cur != NULL )
|
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
if( mbedtls_oid_get_extended_key_usage( &cur->buf, &desc ) != 0 )
|
2014-04-01 17:32:44 +02:00
|
|
|
desc = "???";
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
ret = mbedtls_snprintf( p, n, "%s%s", sep, desc );
|
2015-06-22 11:12:02 +02:00
|
|
|
MBEDTLS_X509_SAFE_SNPRINTF;
|
2014-04-01 17:32:44 +02:00
|
|
|
|
2014-04-01 18:00:07 +02:00
|
|
|
sep = ", ";
|
|
|
|
|
2014-04-01 17:32:44 +02:00
|
|
|
cur = cur->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
*size = n;
|
|
|
|
*buf = p;
|
|
|
|
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
2009-01-03 22:22:43 +01:00
|
|
|
/*
|
2009-05-02 17:13:40 +02:00
|
|
|
* Return an informational string about the certificate.
|
2009-01-03 22:22:43 +01:00
|
|
|
*/
|
2014-04-01 12:19:09 +02:00
|
|
|
#define BEFORE_COLON 18
|
|
|
|
#define BC "18"
|
2015-04-08 12:49:31 +02:00
|
|
|
int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix,
|
2019-02-27 18:38:40 +01:00
|
|
|
const mbedtls_x509_crt *crt )
|
2009-01-03 22:22:43 +01:00
|
|
|
{
|
2011-04-24 10:57:21 +02:00
|
|
|
int ret;
|
|
|
|
size_t n;
|
2009-05-02 17:13:40 +02:00
|
|
|
char *p;
|
2013-08-12 19:45:32 +02:00
|
|
|
char key_size_str[BEFORE_COLON];
|
2019-02-27 18:38:40 +01:00
|
|
|
mbedtls_x509_crt_frame frame;
|
|
|
|
mbedtls_pk_context pk;
|
2019-02-24 17:47:57 +01:00
|
|
|
|
2019-02-27 18:38:40 +01:00
|
|
|
mbedtls_x509_name *issuer = NULL, *subject = NULL;
|
|
|
|
mbedtls_x509_sequence *ext_key_usage = NULL, *subject_alt_names = NULL;
|
2019-02-24 17:47:57 +01:00
|
|
|
mbedtls_x509_crt_sig_info sig_info;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
|
|
|
p = buf;
|
2009-05-02 17:13:40 +02:00
|
|
|
n = size;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2019-02-24 17:47:57 +01:00
|
|
|
memset( &sig_info, 0, sizeof( mbedtls_x509_crt_sig_info ) );
|
2019-02-27 18:38:40 +01:00
|
|
|
mbedtls_pk_init( &pk );
|
|
|
|
|
|
|
|
if( NULL == crt )
|
2016-05-31 15:03:54 +02:00
|
|
|
{
|
|
|
|
ret = mbedtls_snprintf( p, n, "\nCertificate is uninitialised!\n" );
|
2019-05-13 12:58:47 +02:00
|
|
|
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
2016-05-31 15:03:54 +02:00
|
|
|
|
|
|
|
return( (int) ( size - n ) );
|
|
|
|
}
|
|
|
|
|
2019-02-27 18:38:40 +01:00
|
|
|
ret = mbedtls_x509_crt_get_frame( crt, &frame );
|
2019-02-24 17:47:57 +01:00
|
|
|
if( ret != 0 )
|
2019-02-27 18:38:40 +01:00
|
|
|
{
|
|
|
|
ret = MBEDTLS_ERR_X509_FATAL_ERROR;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2019-02-24 17:47:57 +01:00
|
|
|
|
2019-02-27 18:38:40 +01:00
|
|
|
ret = mbedtls_x509_crt_get_subject( crt, &subject );
|
2019-02-24 17:47:57 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
{
|
|
|
|
ret = MBEDTLS_ERR_X509_FATAL_ERROR;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2019-02-27 18:38:40 +01:00
|
|
|
ret = mbedtls_x509_crt_get_issuer( crt, &issuer );
|
2019-02-24 17:47:57 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
{
|
|
|
|
ret = MBEDTLS_ERR_X509_FATAL_ERROR;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2019-02-27 18:38:40 +01:00
|
|
|
ret = mbedtls_x509_crt_get_subject_alt_names( crt, &subject_alt_names );
|
2019-02-24 17:47:57 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
{
|
|
|
|
ret = MBEDTLS_ERR_X509_FATAL_ERROR;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2019-02-27 18:38:40 +01:00
|
|
|
ret = mbedtls_x509_crt_get_ext_key_usage( crt, &ext_key_usage );
|
2019-02-24 17:47:57 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
{
|
|
|
|
ret = MBEDTLS_ERR_X509_FATAL_ERROR;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2019-02-27 18:38:40 +01:00
|
|
|
ret = mbedtls_x509_crt_get_pk( crt, &pk );
|
2019-02-24 17:47:57 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
{
|
|
|
|
ret = MBEDTLS_ERR_X509_FATAL_ERROR;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2019-02-27 18:38:40 +01:00
|
|
|
ret = x509_crt_get_sig_info( &frame, &sig_info );
|
2019-02-24 17:47:57 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
{
|
|
|
|
ret = MBEDTLS_ERR_X509_FATAL_ERROR;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
ret = mbedtls_snprintf( p, n, "%scert. version : %d\n",
|
2019-02-27 18:38:40 +01:00
|
|
|
prefix, frame.version );
|
2019-05-13 12:58:47 +02:00
|
|
|
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2019-02-24 17:47:57 +01:00
|
|
|
{
|
|
|
|
mbedtls_x509_buf serial;
|
2019-02-27 18:38:40 +01:00
|
|
|
serial.p = frame.serial.p;
|
|
|
|
serial.len = frame.serial.len;
|
2019-02-24 17:47:57 +01:00
|
|
|
ret = mbedtls_snprintf( p, n, "%sserial number : ",
|
|
|
|
prefix );
|
2019-05-13 12:58:47 +02:00
|
|
|
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
2019-02-24 17:47:57 +01:00
|
|
|
ret = mbedtls_x509_serial_gets( p, n, &serial );
|
2019-05-13 12:58:47 +02:00
|
|
|
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
2019-02-24 17:47:57 +01:00
|
|
|
}
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
ret = mbedtls_snprintf( p, n, "\n%sissuer name : ", prefix );
|
2019-05-13 12:58:47 +02:00
|
|
|
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
2019-02-27 18:38:40 +01:00
|
|
|
ret = mbedtls_x509_dn_gets( p, n, issuer );
|
2019-05-13 12:58:47 +02:00
|
|
|
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
ret = mbedtls_snprintf( p, n, "\n%ssubject name : ", prefix );
|
2019-05-13 12:58:47 +02:00
|
|
|
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
2019-02-27 18:38:40 +01:00
|
|
|
ret = mbedtls_x509_dn_gets( p, n, subject );
|
2019-05-13 12:58:47 +02:00
|
|
|
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2019-06-25 10:39:21 +02:00
|
|
|
#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME)
|
2015-04-08 12:49:31 +02:00
|
|
|
ret = mbedtls_snprintf( p, n, "\n%sissued on : " \
|
2009-01-03 22:22:43 +01:00
|
|
|
"%04d-%02d-%02d %02d:%02d:%02d", prefix,
|
2019-02-27 18:38:40 +01:00
|
|
|
frame.valid_from.year, frame.valid_from.mon,
|
|
|
|
frame.valid_from.day, frame.valid_from.hour,
|
|
|
|
frame.valid_from.min, frame.valid_from.sec );
|
2019-05-13 12:58:47 +02:00
|
|
|
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
ret = mbedtls_snprintf( p, n, "\n%sexpires on : " \
|
2009-01-03 22:22:43 +01:00
|
|
|
"%04d-%02d-%02d %02d:%02d:%02d", prefix,
|
2019-02-27 18:38:40 +01:00
|
|
|
frame.valid_to.year, frame.valid_to.mon,
|
|
|
|
frame.valid_to.day, frame.valid_to.hour,
|
|
|
|
frame.valid_to.min, frame.valid_to.sec );
|
2019-05-13 12:58:47 +02:00
|
|
|
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
2019-06-25 10:39:21 +02:00
|
|
|
#endif /* MBEDTLS_X509_CRT_REMOVE_TIME */
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix );
|
2019-05-13 12:58:47 +02:00
|
|
|
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2019-02-21 18:13:46 +01:00
|
|
|
ret = mbedtls_x509_sig_alg_gets( p, n, sig_info.sig_pk,
|
|
|
|
sig_info.sig_md, sig_info.sig_opts );
|
2019-05-13 12:58:47 +02:00
|
|
|
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2014-04-01 12:19:09 +02:00
|
|
|
/* Key size */
|
2015-04-08 12:49:31 +02:00
|
|
|
if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON,
|
2019-02-27 18:38:40 +01:00
|
|
|
mbedtls_pk_get_name( &pk ) ) ) != 0 )
|
2013-08-12 19:45:32 +02:00
|
|
|
{
|
|
|
|
return( ret );
|
|
|
|
}
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str,
|
2019-02-27 18:38:40 +01:00
|
|
|
(int) mbedtls_pk_get_bitlen( &pk ) );
|
2019-05-13 12:58:47 +02:00
|
|
|
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2014-04-01 12:19:09 +02:00
|
|
|
/*
|
|
|
|
* Optional extensions
|
|
|
|
*/
|
|
|
|
|
2019-02-27 18:38:40 +01:00
|
|
|
if( frame.ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS )
|
2014-04-01 12:19:09 +02:00
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
ret = mbedtls_snprintf( p, n, "\n%sbasic constraints : CA=%s", prefix,
|
2019-02-27 18:38:40 +01:00
|
|
|
frame.ca_istrue ? "true" : "false" );
|
2019-05-13 12:58:47 +02:00
|
|
|
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
2014-04-01 12:19:09 +02:00
|
|
|
|
2019-02-27 18:38:40 +01:00
|
|
|
if( frame.max_pathlen > 0 )
|
2014-04-01 12:19:09 +02:00
|
|
|
{
|
2019-02-27 18:38:40 +01:00
|
|
|
ret = mbedtls_snprintf( p, n, ", max_pathlen=%d", frame.max_pathlen - 1 );
|
2019-05-13 12:58:47 +02:00
|
|
|
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
2014-04-01 12:19:09 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-27 18:38:40 +01:00
|
|
|
if( frame.ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME )
|
2014-04-01 12:19:09 +02:00
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
ret = mbedtls_snprintf( p, n, "\n%ssubject alt name : ", prefix );
|
2019-05-13 12:58:47 +02:00
|
|
|
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
2014-04-01 13:43:28 +02:00
|
|
|
|
|
|
|
if( ( ret = x509_info_subject_alt_name( &p, &n,
|
2019-02-27 18:38:40 +01:00
|
|
|
subject_alt_names ) ) != 0 )
|
2014-04-01 13:43:28 +02:00
|
|
|
return( ret );
|
2014-04-01 12:19:09 +02:00
|
|
|
}
|
|
|
|
|
2019-02-27 18:38:40 +01:00
|
|
|
if( frame.ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE )
|
2014-04-01 12:19:09 +02:00
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
ret = mbedtls_snprintf( p, n, "\n%scert. type : ", prefix );
|
2019-05-13 12:58:47 +02:00
|
|
|
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
2014-04-01 13:01:11 +02:00
|
|
|
|
2019-02-27 18:38:40 +01:00
|
|
|
if( ( ret = x509_info_cert_type( &p, &n, frame.ns_cert_type ) ) != 0 )
|
2014-04-01 13:01:11 +02:00
|
|
|
return( ret );
|
2014-04-01 12:19:09 +02:00
|
|
|
}
|
|
|
|
|
2019-02-27 18:38:40 +01:00
|
|
|
if( frame.ext_types & MBEDTLS_X509_EXT_KEY_USAGE )
|
2014-04-01 12:19:09 +02:00
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
ret = mbedtls_snprintf( p, n, "\n%skey usage : ", prefix );
|
2019-05-13 12:58:47 +02:00
|
|
|
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
2014-04-01 14:12:11 +02:00
|
|
|
|
2019-02-27 18:38:40 +01:00
|
|
|
if( ( ret = x509_info_key_usage( &p, &n, frame.key_usage ) ) != 0 )
|
2014-04-01 14:12:11 +02:00
|
|
|
return( ret );
|
2014-04-01 12:19:09 +02:00
|
|
|
}
|
|
|
|
|
2019-02-27 18:38:40 +01:00
|
|
|
if( frame.ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE )
|
2014-04-01 12:19:09 +02:00
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
ret = mbedtls_snprintf( p, n, "\n%sext key usage : ", prefix );
|
2019-05-13 12:58:47 +02:00
|
|
|
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
2014-04-01 17:32:44 +02:00
|
|
|
|
|
|
|
if( ( ret = x509_info_ext_key_usage( &p, &n,
|
2019-02-27 18:38:40 +01:00
|
|
|
ext_key_usage ) ) != 0 )
|
2014-04-01 17:32:44 +02:00
|
|
|
return( ret );
|
2014-04-01 12:19:09 +02:00
|
|
|
}
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
ret = mbedtls_snprintf( p, n, "\n" );
|
2019-05-13 12:58:47 +02:00
|
|
|
MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP;
|
2014-04-01 12:19:09 +02:00
|
|
|
|
2019-02-24 17:47:57 +01:00
|
|
|
ret = (int) ( size - n );
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
|
|
|
|
x509_crt_free_sig_info( &sig_info );
|
2019-02-27 18:38:40 +01:00
|
|
|
mbedtls_pk_free( &pk );
|
|
|
|
mbedtls_x509_name_free( issuer );
|
|
|
|
mbedtls_x509_name_free( subject );
|
|
|
|
mbedtls_x509_sequence_free( ext_key_usage );
|
|
|
|
mbedtls_x509_sequence_free( subject_alt_names );
|
2019-02-24 17:47:57 +01:00
|
|
|
|
|
|
|
return( ret );
|
2009-05-02 17:13:40 +02:00
|
|
|
}
|
|
|
|
|
2015-04-20 11:38:13 +02:00
|
|
|
struct x509_crt_verify_string {
|
|
|
|
int code;
|
|
|
|
const char *string;
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct x509_crt_verify_string x509_crt_verify_strings[] = {
|
2015-04-20 13:19:02 +02:00
|
|
|
{ MBEDTLS_X509_BADCERT_EXPIRED, "The certificate validity has expired" },
|
2015-04-20 11:38:13 +02:00
|
|
|
{ MBEDTLS_X509_BADCERT_REVOKED, "The certificate has been revoked (is on a CRL)" },
|
|
|
|
{ MBEDTLS_X509_BADCERT_CN_MISMATCH, "The certificate Common Name (CN) does not match with the expected CN" },
|
|
|
|
{ MBEDTLS_X509_BADCERT_NOT_TRUSTED, "The certificate is not correctly signed by the trusted CA" },
|
|
|
|
{ MBEDTLS_X509_BADCRL_NOT_TRUSTED, "The CRL is not correctly signed by the trusted CA" },
|
|
|
|
{ MBEDTLS_X509_BADCRL_EXPIRED, "The CRL is expired" },
|
2015-04-20 13:19:02 +02:00
|
|
|
{ MBEDTLS_X509_BADCERT_MISSING, "Certificate was missing" },
|
|
|
|
{ MBEDTLS_X509_BADCERT_SKIP_VERIFY, "Certificate verification was skipped" },
|
|
|
|
{ MBEDTLS_X509_BADCERT_OTHER, "Other reason (can be used by verify callback)" },
|
2015-04-20 11:38:13 +02:00
|
|
|
{ MBEDTLS_X509_BADCERT_FUTURE, "The certificate validity starts in the future" },
|
2015-04-20 13:19:02 +02:00
|
|
|
{ MBEDTLS_X509_BADCRL_FUTURE, "The CRL is from the future" },
|
|
|
|
{ MBEDTLS_X509_BADCERT_KEY_USAGE, "Usage does not match the keyUsage extension" },
|
|
|
|
{ MBEDTLS_X509_BADCERT_EXT_KEY_USAGE, "Usage does not match the extendedKeyUsage extension" },
|
|
|
|
{ MBEDTLS_X509_BADCERT_NS_CERT_TYPE, "Usage does not match the nsCertType extension" },
|
2015-06-15 10:39:46 +02:00
|
|
|
{ MBEDTLS_X509_BADCERT_BAD_MD, "The certificate is signed with an unacceptable hash." },
|
|
|
|
{ MBEDTLS_X509_BADCERT_BAD_PK, "The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA)." },
|
|
|
|
{ MBEDTLS_X509_BADCERT_BAD_KEY, "The certificate is signed with an unacceptable key (eg bad curve, RSA too short)." },
|
|
|
|
{ MBEDTLS_X509_BADCRL_BAD_MD, "The CRL is signed with an unacceptable hash." },
|
|
|
|
{ MBEDTLS_X509_BADCRL_BAD_PK, "The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA)." },
|
|
|
|
{ MBEDTLS_X509_BADCRL_BAD_KEY, "The CRL is signed with an unacceptable key (eg bad curve, RSA too short)." },
|
2015-04-20 11:38:13 +02:00
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix,
|
2015-05-11 19:54:43 +02:00
|
|
|
uint32_t flags )
|
2015-04-20 11:38:13 +02:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
const struct x509_crt_verify_string *cur;
|
|
|
|
char *p = buf;
|
|
|
|
size_t n = size;
|
|
|
|
|
|
|
|
for( cur = x509_crt_verify_strings; cur->string != NULL ; cur++ )
|
|
|
|
{
|
|
|
|
if( ( flags & cur->code ) == 0 )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
ret = mbedtls_snprintf( p, n, "%s%s\n", prefix, cur->string );
|
2015-06-22 11:12:02 +02:00
|
|
|
MBEDTLS_X509_SAFE_SNPRINTF;
|
2015-04-20 11:38:13 +02:00
|
|
|
flags ^= cur->code;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( flags != 0 )
|
|
|
|
{
|
|
|
|
ret = mbedtls_snprintf( p, n, "%sUnknown reason "
|
|
|
|
"(this should not happen)\n", prefix );
|
2015-06-22 11:12:02 +02:00
|
|
|
MBEDTLS_X509_SAFE_SNPRINTF;
|
2015-04-20 11:38:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return( (int) ( size - n ) );
|
|
|
|
}
|
2019-06-10 16:08:43 +02:00
|
|
|
#endif /* !MBEDTLS_X509_REMOVE_INFO */
|
2015-04-20 11:38:13 +02:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
|
2019-02-25 14:55:33 +01:00
|
|
|
static int x509_crt_check_key_usage_frame( const mbedtls_x509_crt_frame *crt,
|
|
|
|
unsigned int usage )
|
2014-04-09 09:50:03 +02:00
|
|
|
{
|
2015-06-23 10:48:44 +02:00
|
|
|
unsigned int usage_must, usage_may;
|
|
|
|
unsigned int may_mask = MBEDTLS_X509_KU_ENCIPHER_ONLY
|
|
|
|
| MBEDTLS_X509_KU_DECIPHER_ONLY;
|
|
|
|
|
|
|
|
if( ( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE ) == 0 )
|
|
|
|
return( 0 );
|
|
|
|
|
|
|
|
usage_must = usage & ~may_mask;
|
|
|
|
|
|
|
|
if( ( ( crt->key_usage & ~may_mask ) & usage_must ) != usage_must )
|
|
|
|
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
|
|
|
|
|
|
|
|
usage_may = usage & may_mask;
|
|
|
|
|
|
|
|
if( ( ( crt->key_usage & may_mask ) | usage_may ) != usage_may )
|
2015-04-08 12:49:31 +02:00
|
|
|
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
|
2014-04-09 09:50:03 +02:00
|
|
|
|
|
|
|
return( 0 );
|
|
|
|
}
|
2019-02-25 14:55:33 +01:00
|
|
|
|
|
|
|
int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt,
|
|
|
|
unsigned int usage )
|
|
|
|
{
|
|
|
|
int ret;
|
2019-05-20 17:26:34 +02:00
|
|
|
mbedtls_x509_crt_frame const *frame;
|
2019-03-05 14:50:56 +01:00
|
|
|
ret = mbedtls_x509_crt_frame_acquire( crt, &frame );
|
2019-02-25 14:55:33 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
return( MBEDTLS_ERR_X509_FATAL_ERROR );
|
|
|
|
|
|
|
|
ret = x509_crt_check_key_usage_frame( frame, usage );
|
2019-03-05 14:50:56 +01:00
|
|
|
mbedtls_x509_crt_frame_release( crt );
|
2019-02-25 14:55:33 +01:00
|
|
|
|
|
|
|
return( ret );
|
|
|
|
}
|
2014-04-09 09:50:03 +02:00
|
|
|
#endif
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
|
2019-02-21 22:10:51 +01:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
const char *oid;
|
|
|
|
size_t oid_len;
|
|
|
|
} x509_crt_check_ext_key_usage_cb_ctx_t;
|
|
|
|
|
|
|
|
static int x509_crt_check_ext_key_usage_cb( void *ctx,
|
|
|
|
int tag,
|
|
|
|
unsigned char *data,
|
|
|
|
size_t data_len )
|
|
|
|
{
|
|
|
|
x509_crt_check_ext_key_usage_cb_ctx_t *cb_ctx =
|
|
|
|
(x509_crt_check_ext_key_usage_cb_ctx_t *) ctx;
|
|
|
|
((void) tag);
|
|
|
|
|
|
|
|
if( MBEDTLS_OID_CMP_RAW( MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE,
|
|
|
|
data, data_len ) == 0 )
|
|
|
|
{
|
|
|
|
return( 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( data_len == cb_ctx->oid_len && memcmp( data, cb_ctx->oid,
|
|
|
|
data_len ) == 0 )
|
|
|
|
{
|
|
|
|
return( 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt,
|
2019-02-21 15:28:12 +01:00
|
|
|
const char *usage_oid,
|
|
|
|
size_t usage_len )
|
2014-04-10 17:53:56 +02:00
|
|
|
{
|
2019-02-21 15:28:12 +01:00
|
|
|
int ret;
|
2019-05-20 17:26:34 +02:00
|
|
|
mbedtls_x509_crt_frame const *frame;
|
2019-02-21 15:28:12 +01:00
|
|
|
unsigned ext_types;
|
|
|
|
unsigned char *p, *end;
|
2019-02-21 22:10:51 +01:00
|
|
|
x509_crt_check_ext_key_usage_cb_ctx_t cb_ctx = { usage_oid, usage_len };
|
2014-04-10 17:53:56 +02:00
|
|
|
|
2019-02-25 14:50:14 +01:00
|
|
|
ret = mbedtls_x509_crt_frame_acquire( crt, &frame );
|
2019-02-25 19:11:42 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
return( MBEDTLS_ERR_X509_FATAL_ERROR );
|
2019-02-21 15:28:12 +01:00
|
|
|
|
2019-02-25 19:11:42 +01:00
|
|
|
/* Extension is not mandatory, absent means no restriction */
|
|
|
|
ext_types = frame->ext_types;
|
|
|
|
if( ( ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) != 0 )
|
|
|
|
{
|
|
|
|
p = frame->ext_key_usage_raw.p;
|
|
|
|
end = p + frame->ext_key_usage_raw.len;
|
|
|
|
|
|
|
|
ret = mbedtls_asn1_traverse_sequence_of( &p, end,
|
|
|
|
0xFF, MBEDTLS_ASN1_OID, 0, 0,
|
|
|
|
x509_crt_check_ext_key_usage_cb,
|
|
|
|
&cb_ctx );
|
|
|
|
if( ret == 1 )
|
|
|
|
ret = 0;
|
|
|
|
else
|
|
|
|
ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA;
|
|
|
|
}
|
2014-04-10 17:53:56 +02:00
|
|
|
|
2019-03-05 14:50:56 +01:00
|
|
|
mbedtls_x509_crt_frame_release( crt );
|
2019-02-25 19:11:42 +01:00
|
|
|
return( ret );
|
2014-04-10 17:53:56 +02:00
|
|
|
}
|
2015-04-08 12:49:31 +02:00
|
|
|
#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
|
2014-04-10 17:53:56 +02:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
#if defined(MBEDTLS_X509_CRL_PARSE_C)
|
2009-05-03 12:18:48 +02:00
|
|
|
/*
|
|
|
|
* Return 1 if the certificate is revoked, or 0 otherwise.
|
|
|
|
*/
|
2019-02-22 16:01:03 +01:00
|
|
|
static int x509_serial_is_revoked( unsigned char const *serial,
|
|
|
|
size_t serial_len,
|
|
|
|
const mbedtls_x509_crl *crl )
|
2009-05-03 12:18:48 +02:00
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
const mbedtls_x509_crl_entry *cur = &crl->entry;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2009-05-03 12:18:48 +02:00
|
|
|
while( cur != NULL && cur->serial.len != 0 )
|
|
|
|
{
|
2019-02-22 16:01:03 +01:00
|
|
|
if( serial_len == cur->serial.len &&
|
|
|
|
memcmp( serial, cur->serial.p, serial_len ) == 0 )
|
2009-05-03 12:18:48 +02:00
|
|
|
{
|
2015-06-02 11:38:50 +02:00
|
|
|
if( mbedtls_x509_time_is_past( &cur->revocation_date ) )
|
2009-05-03 12:18:48 +02:00
|
|
|
return( 1 );
|
|
|
|
}
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2009-05-03 12:18:48 +02:00
|
|
|
cur = cur->next;
|
|
|
|
}
|
2009-01-03 22:22:43 +01:00
|
|
|
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
2019-02-22 16:01:03 +01:00
|
|
|
int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt,
|
|
|
|
const mbedtls_x509_crl *crl )
|
|
|
|
{
|
2019-02-25 19:12:00 +01:00
|
|
|
int ret;
|
2019-05-20 17:26:34 +02:00
|
|
|
mbedtls_x509_crt_frame const *frame;
|
2019-02-25 19:12:00 +01:00
|
|
|
|
2019-02-25 14:50:14 +01:00
|
|
|
ret = mbedtls_x509_crt_frame_acquire( crt, &frame );
|
2019-02-25 19:12:00 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
return( MBEDTLS_ERR_X509_FATAL_ERROR );
|
|
|
|
|
|
|
|
ret = x509_serial_is_revoked( frame->serial.p,
|
|
|
|
frame->serial.len,
|
|
|
|
crl );
|
2019-03-05 14:50:56 +01:00
|
|
|
mbedtls_x509_crt_frame_release( crt );
|
2019-02-25 19:12:00 +01:00
|
|
|
return( ret );
|
2019-02-22 16:01:03 +01:00
|
|
|
}
|
|
|
|
|
2011-01-16 22:12:10 +01:00
|
|
|
/*
|
2016-02-22 11:36:55 +01:00
|
|
|
* Check that the given certificate is not revoked according to the CRL.
|
2017-10-18 14:20:24 +02:00
|
|
|
* Skip validation if no CRL for the given CA is present.
|
2011-01-16 22:12:10 +01:00
|
|
|
*/
|
2019-02-22 16:01:03 +01:00
|
|
|
static int x509_crt_verifycrl( unsigned char *crt_serial,
|
|
|
|
size_t crt_serial_len,
|
2019-02-25 19:12:46 +01:00
|
|
|
mbedtls_x509_crt *ca_crt,
|
2015-06-15 10:39:46 +02:00
|
|
|
mbedtls_x509_crl *crl_list,
|
|
|
|
const mbedtls_x509_crt_profile *profile )
|
2011-01-16 22:12:10 +01:00
|
|
|
{
|
2019-02-25 19:12:46 +01:00
|
|
|
int ret;
|
2011-01-16 22:12:10 +01:00
|
|
|
int flags = 0;
|
2015-04-08 12:49:31 +02:00
|
|
|
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
|
|
|
|
const mbedtls_md_info_t *md_info;
|
2019-02-25 19:12:46 +01:00
|
|
|
mbedtls_x509_buf_raw ca_subject;
|
|
|
|
mbedtls_pk_context *pk;
|
|
|
|
int can_sign;
|
2011-01-16 22:12:10 +01:00
|
|
|
|
2019-02-25 19:12:46 +01:00
|
|
|
if( ca_crt == NULL )
|
2012-09-28 09:10:55 +02:00
|
|
|
return( flags );
|
|
|
|
|
2019-02-25 19:12:46 +01:00
|
|
|
{
|
2019-05-20 17:26:34 +02:00
|
|
|
mbedtls_x509_crt_frame const *ca;
|
2019-02-25 14:50:14 +01:00
|
|
|
ret = mbedtls_x509_crt_frame_acquire( ca_crt, &ca );
|
2019-02-25 19:12:46 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
return( MBEDTLS_X509_BADCRL_NOT_TRUSTED );
|
|
|
|
|
|
|
|
ca_subject = ca->subject_raw;
|
|
|
|
|
|
|
|
can_sign = 0;
|
|
|
|
if( x509_crt_check_key_usage_frame( ca,
|
|
|
|
MBEDTLS_X509_KU_CRL_SIGN ) == 0 )
|
|
|
|
{
|
|
|
|
can_sign = 1;
|
|
|
|
}
|
|
|
|
|
2019-03-05 14:50:56 +01:00
|
|
|
mbedtls_x509_crt_frame_release( ca_crt );
|
2019-02-25 19:12:46 +01:00
|
|
|
}
|
|
|
|
|
2019-02-25 14:50:14 +01:00
|
|
|
ret = mbedtls_x509_crt_pk_acquire( ca_crt, &pk );
|
2019-02-25 19:12:46 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
return( MBEDTLS_X509_BADCRL_NOT_TRUSTED );
|
|
|
|
|
2012-09-28 09:10:55 +02:00
|
|
|
while( crl_list != NULL )
|
2011-01-16 22:12:10 +01:00
|
|
|
{
|
2012-09-28 09:10:55 +02:00
|
|
|
if( crl_list->version == 0 ||
|
2019-03-04 15:43:43 +01:00
|
|
|
mbedtls_x509_name_cmp_raw( &crl_list->issuer_raw,
|
2019-02-25 19:12:46 +01:00
|
|
|
&ca_subject, NULL, NULL ) != 0 )
|
2011-01-16 22:12:10 +01:00
|
|
|
{
|
|
|
|
crl_list = crl_list->next;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2014-04-08 15:10:07 +02:00
|
|
|
/*
|
|
|
|
* Check if the CA is configured to sign CRLs
|
|
|
|
*/
|
2015-04-08 12:49:31 +02:00
|
|
|
#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
|
2019-02-25 19:12:46 +01:00
|
|
|
if( !can_sign )
|
2014-04-08 15:10:07 +02:00
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
|
2014-04-08 15:10:07 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2011-01-16 22:12:10 +01:00
|
|
|
/*
|
|
|
|
* Check if CRL is correctly signed by the trusted CA
|
|
|
|
*/
|
2015-06-15 16:17:55 +02:00
|
|
|
if( x509_profile_check_md_alg( profile, crl_list->sig_md ) != 0 )
|
|
|
|
flags |= MBEDTLS_X509_BADCRL_BAD_MD;
|
|
|
|
|
|
|
|
if( x509_profile_check_pk_alg( profile, crl_list->sig_pk ) != 0 )
|
|
|
|
flags |= MBEDTLS_X509_BADCRL_BAD_PK;
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
md_info = mbedtls_md_info_from_type( crl_list->sig_md );
|
2017-06-26 12:22:17 +02:00
|
|
|
if( mbedtls_md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash ) != 0 )
|
2013-04-07 22:00:46 +02:00
|
|
|
{
|
2017-06-26 12:22:17 +02:00
|
|
|
/* Note: this can't happen except after an internal error */
|
2015-04-08 12:49:31 +02:00
|
|
|
flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
|
2013-04-07 22:00:46 +02:00
|
|
|
break;
|
|
|
|
}
|
2011-01-16 22:12:10 +01:00
|
|
|
|
2019-02-25 19:12:46 +01:00
|
|
|
if( x509_profile_check_key( profile, pk ) != 0 )
|
2015-06-15 16:17:55 +02:00
|
|
|
flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
|
2015-06-15 10:39:46 +02:00
|
|
|
|
2019-02-25 19:12:46 +01:00
|
|
|
if( mbedtls_pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, pk,
|
2015-04-08 12:49:31 +02:00
|
|
|
crl_list->sig_md, hash, mbedtls_md_get_size( md_info ),
|
2014-06-05 17:53:52 +02:00
|
|
|
crl_list->sig.p, crl_list->sig.len ) != 0 )
|
2011-01-16 22:12:10 +01:00
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
|
2013-08-12 18:41:18 +02:00
|
|
|
break;
|
2011-01-16 22:12:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check for validity of CRL (Do not drop out)
|
|
|
|
*/
|
2015-06-02 11:38:50 +02:00
|
|
|
if( mbedtls_x509_time_is_past( &crl_list->next_update ) )
|
2015-04-08 12:49:31 +02:00
|
|
|
flags |= MBEDTLS_X509_BADCRL_EXPIRED;
|
2011-01-16 22:12:10 +01:00
|
|
|
|
2015-06-02 11:38:50 +02:00
|
|
|
if( mbedtls_x509_time_is_future( &crl_list->this_update ) )
|
2015-04-20 13:19:02 +02:00
|
|
|
flags |= MBEDTLS_X509_BADCRL_FUTURE;
|
2014-03-10 13:15:18 +01:00
|
|
|
|
2011-01-16 22:12:10 +01:00
|
|
|
/*
|
|
|
|
* Check if certificate is revoked
|
|
|
|
*/
|
2019-02-22 16:01:03 +01:00
|
|
|
if( x509_serial_is_revoked( crt_serial, crt_serial_len,
|
|
|
|
crl_list ) )
|
2011-01-16 22:12:10 +01:00
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
flags |= MBEDTLS_X509_BADCERT_REVOKED;
|
2011-01-16 22:12:10 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
crl_list = crl_list->next;
|
|
|
|
}
|
2015-06-15 16:17:55 +02:00
|
|
|
|
2019-03-05 14:50:56 +01:00
|
|
|
mbedtls_x509_crt_pk_release( ca_crt );
|
2014-06-17 14:06:49 +02:00
|
|
|
return( flags );
|
2011-01-16 22:12:10 +01:00
|
|
|
}
|
2015-04-08 12:49:31 +02:00
|
|
|
#endif /* MBEDTLS_X509_CRL_PARSE_C */
|
2011-01-16 22:12:10 +01:00
|
|
|
|
2017-07-03 19:26:25 +02:00
|
|
|
/*
|
|
|
|
* Check the signature of a certificate by its parent
|
|
|
|
*/
|
2019-02-25 14:50:41 +01:00
|
|
|
static int x509_crt_check_signature( const mbedtls_x509_crt_sig_info *sig_info,
|
2017-07-17 10:26:19 +02:00
|
|
|
mbedtls_x509_crt *parent,
|
|
|
|
mbedtls_x509_crt_restart_ctx *rs_ctx )
|
2017-07-03 19:26:25 +02:00
|
|
|
{
|
2019-02-25 15:45:31 +01:00
|
|
|
int ret;
|
|
|
|
mbedtls_pk_context *pk;
|
|
|
|
|
2019-02-25 14:50:14 +01:00
|
|
|
ret = mbedtls_x509_crt_pk_acquire( parent, &pk );
|
2019-02-25 15:45:31 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
return( MBEDTLS_ERR_X509_FATAL_ERROR );
|
|
|
|
|
2017-07-17 10:26:19 +02:00
|
|
|
/* Skip expensive computation on obvious mismatch */
|
2019-02-25 15:45:31 +01:00
|
|
|
if( ! mbedtls_pk_can_do( pk, sig_info->sig_pk ) )
|
|
|
|
{
|
|
|
|
ret = -1;
|
|
|
|
goto exit;
|
|
|
|
}
|
2017-07-17 10:26:19 +02:00
|
|
|
|
2019-02-25 15:45:31 +01:00
|
|
|
#if !( defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) )
|
|
|
|
((void) rs_ctx);
|
|
|
|
#else
|
|
|
|
if( rs_ctx != NULL && sig_info->sig_pk == MBEDTLS_PK_ECDSA )
|
2017-07-17 10:26:19 +02:00
|
|
|
{
|
2019-02-25 15:45:31 +01:00
|
|
|
ret = mbedtls_pk_verify_restartable( pk,
|
2019-02-25 14:50:41 +01:00
|
|
|
sig_info->sig_md,
|
|
|
|
sig_info->crt_hash, sig_info->crt_hash_len,
|
|
|
|
sig_info->sig.p, sig_info->sig.len,
|
2019-02-25 15:45:31 +01:00
|
|
|
&rs_ctx->pk );
|
2017-07-03 19:26:25 +02:00
|
|
|
}
|
2019-02-25 15:45:31 +01:00
|
|
|
else
|
2017-07-17 10:26:19 +02:00
|
|
|
#endif
|
2019-02-25 15:45:31 +01:00
|
|
|
{
|
|
|
|
ret = mbedtls_pk_verify_ext( sig_info->sig_pk,
|
|
|
|
sig_info->sig_opts,
|
|
|
|
pk,
|
|
|
|
sig_info->sig_md,
|
|
|
|
sig_info->crt_hash, sig_info->crt_hash_len,
|
|
|
|
sig_info->sig.p, sig_info->sig.len );
|
|
|
|
}
|
2017-07-03 19:26:25 +02:00
|
|
|
|
2019-02-25 15:45:31 +01:00
|
|
|
exit:
|
2019-03-05 14:50:56 +01:00
|
|
|
mbedtls_x509_crt_pk_release( parent );
|
2019-02-25 15:45:31 +01:00
|
|
|
return( ret );
|
2017-07-03 19:26:25 +02:00
|
|
|
}
|
|
|
|
|
2014-04-08 13:18:01 +02:00
|
|
|
/*
|
2014-04-09 14:30:11 +02:00
|
|
|
* Check if 'parent' is a suitable parent (signing CA) for 'child'.
|
|
|
|
* Return 0 if yes, -1 if not.
|
2014-06-24 11:49:16 +02:00
|
|
|
*
|
|
|
|
* top means parent is a locally-trusted certificate
|
2014-04-08 13:18:01 +02:00
|
|
|
*/
|
2019-02-25 15:46:49 +01:00
|
|
|
static int x509_crt_check_parent( const mbedtls_x509_crt_sig_info *sig_info,
|
|
|
|
const mbedtls_x509_crt_frame *parent,
|
2017-07-04 00:49:31 +02:00
|
|
|
int top )
|
2014-04-08 13:18:01 +02:00
|
|
|
{
|
2014-06-24 11:49:16 +02:00
|
|
|
int need_ca_bit;
|
|
|
|
|
2014-06-19 12:18:08 +02:00
|
|
|
/* Parent must be the issuer */
|
2019-02-25 15:46:49 +01:00
|
|
|
if( mbedtls_x509_name_cmp_raw( &sig_info->issuer_raw,
|
|
|
|
&parent->subject_raw,
|
2019-02-21 15:31:51 +01:00
|
|
|
NULL, NULL ) != 0 )
|
2019-02-21 14:58:38 +01:00
|
|
|
{
|
2014-04-09 14:30:11 +02:00
|
|
|
return( -1 );
|
2019-02-21 14:58:38 +01:00
|
|
|
}
|
2014-04-08 13:18:01 +02:00
|
|
|
|
2014-06-24 11:49:16 +02:00
|
|
|
/* Parent must have the basicConstraints CA bit set as a general rule */
|
|
|
|
need_ca_bit = 1;
|
|
|
|
|
|
|
|
/* Exception: v1/v2 certificates that are locally trusted. */
|
|
|
|
if( top && parent->version < 3 )
|
|
|
|
need_ca_bit = 0;
|
|
|
|
|
|
|
|
if( need_ca_bit && ! parent->ca_istrue )
|
|
|
|
return( -1 );
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
|
2014-06-24 11:49:16 +02:00
|
|
|
if( need_ca_bit &&
|
2019-02-25 15:46:49 +01:00
|
|
|
x509_crt_check_key_usage_frame( parent,
|
|
|
|
MBEDTLS_X509_KU_KEY_CERT_SIGN ) != 0 )
|
2014-06-24 11:49:16 +02:00
|
|
|
{
|
2014-04-09 14:30:11 +02:00
|
|
|
return( -1 );
|
2014-06-24 11:49:16 +02:00
|
|
|
}
|
2014-04-08 15:10:07 +02:00
|
|
|
#endif
|
|
|
|
|
2014-04-09 14:30:11 +02:00
|
|
|
return( 0 );
|
2014-04-08 13:18:01 +02:00
|
|
|
}
|
|
|
|
|
2017-06-29 12:27:23 +02:00
|
|
|
/*
|
2017-06-29 12:55:27 +02:00
|
|
|
* Find a suitable parent for child in candidates, or return NULL.
|
|
|
|
*
|
|
|
|
* Here suitable is defined as:
|
2017-07-03 18:30:43 +02:00
|
|
|
* 1. subject name matches child's issuer
|
|
|
|
* 2. if necessary, the CA bit is set and key usage allows signing certs
|
|
|
|
* 3. for trusted roots, the signature is correct
|
2017-07-14 12:04:14 +02:00
|
|
|
* (for intermediates, the signature is checked and the result reported)
|
2017-07-03 18:30:43 +02:00
|
|
|
* 4. pathlen constraints are satisfied
|
2017-06-29 12:55:27 +02:00
|
|
|
*
|
2017-08-08 18:09:14 +02:00
|
|
|
* If there's a suitable candidate which is also time-valid, return the first
|
|
|
|
* such. Otherwise, return the first suitable candidate (or NULL if there is
|
|
|
|
* none).
|
2017-06-29 12:55:27 +02:00
|
|
|
*
|
|
|
|
* The rationale for this rule is that someone could have a list of trusted
|
|
|
|
* roots with two versions on the same root with different validity periods.
|
|
|
|
* (At least one user reported having such a list and wanted it to just work.)
|
|
|
|
* The reason we don't just require time-validity is that generally there is
|
|
|
|
* only one version, and if it's expired we want the flags to state that
|
|
|
|
* rather than NOT_TRUSTED, as would be the case if we required it here.
|
2017-07-03 18:30:43 +02:00
|
|
|
*
|
|
|
|
* The rationale for rule 3 (signature for trusted roots) is that users might
|
|
|
|
* have two versions of the same CA with different keys in their list, and the
|
2017-07-04 00:33:39 +02:00
|
|
|
* way we select the correct one is by checking the signature (as we don't
|
|
|
|
* rely on key identifier extensions). (This is one way users might choose to
|
|
|
|
* handle key rollover, another relies on self-issued certs, see [SIRO].)
|
2017-08-17 10:52:20 +02:00
|
|
|
*
|
|
|
|
* Arguments:
|
2018-03-07 10:00:57 +01:00
|
|
|
* - [in] child: certificate for which we're looking for a parent
|
|
|
|
* - [in] candidates: chained list of potential parents
|
2018-06-12 12:40:54 +02:00
|
|
|
* - [out] r_parent: parent found (or NULL)
|
|
|
|
* - [out] r_signature_is_good: 1 if child signature by parent is valid, or 0
|
2018-03-07 10:00:57 +01:00
|
|
|
* - [in] top: 1 if candidates consists of trusted roots, ie we're at the top
|
|
|
|
* of the chain, 0 otherwise
|
|
|
|
* - [in] path_cnt: number of intermediates seen so far
|
|
|
|
* - [in] self_cnt: number of self-signed intermediates seen so far
|
|
|
|
* (will never be greater than path_cnt)
|
2018-06-12 12:40:54 +02:00
|
|
|
* - [in-out] rs_ctx: context for restarting operations
|
2018-03-07 10:00:57 +01:00
|
|
|
*
|
|
|
|
* Return value:
|
2018-06-12 12:40:54 +02:00
|
|
|
* - 0 on success
|
|
|
|
* - MBEDTLS_ERR_ECP_IN_PROGRESS otherwise
|
2017-06-29 12:27:23 +02:00
|
|
|
*/
|
2017-07-17 10:26:19 +02:00
|
|
|
static int x509_crt_find_parent_in(
|
2019-02-25 14:50:41 +01:00
|
|
|
mbedtls_x509_crt_sig_info const *child_sig,
|
2017-07-17 10:26:19 +02:00
|
|
|
mbedtls_x509_crt *candidates,
|
|
|
|
mbedtls_x509_crt **r_parent,
|
|
|
|
int *r_signature_is_good,
|
|
|
|
int top,
|
2017-08-28 13:25:55 +02:00
|
|
|
unsigned path_cnt,
|
|
|
|
unsigned self_cnt,
|
2017-07-17 10:26:19 +02:00
|
|
|
mbedtls_x509_crt_restart_ctx *rs_ctx )
|
2017-06-29 12:27:23 +02:00
|
|
|
{
|
2017-07-17 10:26:19 +02:00
|
|
|
int ret;
|
2019-06-10 12:12:33 +02:00
|
|
|
mbedtls_x509_crt *parent_crt;
|
|
|
|
int signature_is_good;
|
|
|
|
|
|
|
|
#if defined(MBEDTLS_HAVE_TIME_DATE)
|
|
|
|
mbedtls_x509_crt *fallback_parent;
|
|
|
|
int fallback_signature_is_good;
|
|
|
|
#endif /* MBEDTLS_HAVE_TIME_DATE */
|
2017-08-14 18:04:19 +02:00
|
|
|
|
|
|
|
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
2017-08-23 11:20:48 +02:00
|
|
|
/* did we have something in progress? */
|
2017-08-14 18:04:19 +02:00
|
|
|
if( rs_ctx != NULL && rs_ctx->parent != NULL )
|
|
|
|
{
|
2017-08-23 11:20:48 +02:00
|
|
|
/* restore saved state */
|
2019-02-25 15:46:49 +01:00
|
|
|
parent_crt = rs_ctx->parent;
|
2019-06-10 12:12:33 +02:00
|
|
|
#if defined(MBEDTLS_HAVE_TIME_DATE)
|
2017-08-14 18:04:19 +02:00
|
|
|
fallback_parent = rs_ctx->fallback_parent;
|
2018-07-02 12:33:14 +02:00
|
|
|
fallback_signature_is_good = rs_ctx->fallback_signature_is_good;
|
2019-06-10 12:12:33 +02:00
|
|
|
#endif /* MBEDTLS_HAVE_TIME_DATE */
|
2017-08-14 18:04:19 +02:00
|
|
|
|
2017-08-23 11:20:48 +02:00
|
|
|
/* clear saved state */
|
|
|
|
rs_ctx->parent = NULL;
|
2019-06-10 12:12:33 +02:00
|
|
|
#if defined(MBEDTLS_HAVE_TIME_DATE)
|
2017-08-23 11:20:48 +02:00
|
|
|
rs_ctx->fallback_parent = NULL;
|
2018-07-02 12:33:14 +02:00
|
|
|
rs_ctx->fallback_signature_is_good = 0;
|
2019-06-10 12:12:33 +02:00
|
|
|
#endif /* MBEDTLS_HAVE_TIME_DATE */
|
2017-08-23 11:20:48 +02:00
|
|
|
|
|
|
|
/* resume where we left */
|
2017-08-14 18:04:19 +02:00
|
|
|
goto check_signature;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-06-10 12:12:33 +02:00
|
|
|
#if defined(MBEDTLS_HAVE_TIME_DATE)
|
2017-08-14 18:04:19 +02:00
|
|
|
fallback_parent = NULL;
|
2018-07-02 12:33:14 +02:00
|
|
|
fallback_signature_is_good = 0;
|
2019-06-10 12:12:33 +02:00
|
|
|
#endif /* MBEDTLS_HAVE_TIME_DATE */
|
2017-06-29 12:27:23 +02:00
|
|
|
|
2019-02-25 15:46:49 +01:00
|
|
|
for( parent_crt = candidates; parent_crt != NULL;
|
|
|
|
parent_crt = parent_crt->next )
|
2017-06-29 12:27:23 +02:00
|
|
|
{
|
2019-02-24 18:47:46 +01:00
|
|
|
int parent_valid, parent_match, path_len_ok;
|
|
|
|
|
|
|
|
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
|
|
|
check_signature:
|
|
|
|
#endif
|
|
|
|
|
|
|
|
parent_valid = parent_match = path_len_ok = 0;
|
|
|
|
{
|
2019-05-20 17:26:34 +02:00
|
|
|
mbedtls_x509_crt_frame const *parent;
|
2019-02-24 18:47:46 +01:00
|
|
|
|
2019-02-25 14:50:14 +01:00
|
|
|
ret = mbedtls_x509_crt_frame_acquire( parent_crt, &parent );
|
2019-02-25 15:46:49 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
return( MBEDTLS_ERR_X509_FATAL_ERROR );
|
2017-06-29 12:27:23 +02:00
|
|
|
|
2019-06-25 10:39:21 +02:00
|
|
|
#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME)
|
2019-06-10 12:14:24 +02:00
|
|
|
if( !mbedtls_x509_time_is_past( &parent->valid_to ) &&
|
|
|
|
!mbedtls_x509_time_is_future( &parent->valid_from ) )
|
2019-07-30 16:03:06 +02:00
|
|
|
#endif /* !MBEDTLS_X509_CRT_REMOVE_TIME */
|
2019-02-25 15:46:49 +01:00
|
|
|
{
|
|
|
|
parent_valid = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* basic parenting skills (name, CA bit, key usage) */
|
|
|
|
if( x509_crt_check_parent( child_sig, parent, top ) == 0 )
|
|
|
|
parent_match = 1;
|
|
|
|
|
|
|
|
/* +1 because the stored max_pathlen is 1 higher
|
|
|
|
* than the actual value */
|
|
|
|
if( !( parent->max_pathlen > 0 &&
|
|
|
|
(size_t) parent->max_pathlen < 1 + path_cnt - self_cnt ) )
|
|
|
|
{
|
|
|
|
path_len_ok = 1;
|
|
|
|
}
|
|
|
|
|
2019-03-05 14:50:56 +01:00
|
|
|
mbedtls_x509_crt_frame_release( parent_crt );
|
2017-06-29 12:38:42 +02:00
|
|
|
}
|
|
|
|
|
2019-02-24 18:47:46 +01:00
|
|
|
if( parent_match == 0 || path_len_ok == 0 )
|
|
|
|
continue;
|
|
|
|
|
2017-07-03 18:30:43 +02:00
|
|
|
/* Signature */
|
2019-02-25 15:46:49 +01:00
|
|
|
ret = x509_crt_check_signature( child_sig, parent_crt, rs_ctx );
|
2017-07-17 10:26:19 +02:00
|
|
|
|
|
|
|
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
2017-08-14 18:04:19 +02:00
|
|
|
if( rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
|
|
|
|
{
|
|
|
|
/* save state */
|
2019-02-25 15:46:49 +01:00
|
|
|
rs_ctx->parent = parent_crt;
|
2019-06-10 12:12:33 +02:00
|
|
|
#if defined(MBEDTLS_HAVE_TIME_DATE)
|
2017-08-14 18:04:19 +02:00
|
|
|
rs_ctx->fallback_parent = fallback_parent;
|
2018-07-02 12:33:14 +02:00
|
|
|
rs_ctx->fallback_signature_is_good = fallback_signature_is_good;
|
2019-06-10 12:12:33 +02:00
|
|
|
#endif /* MBEDTLS_HAVE_TIME_DATE */
|
2017-08-14 18:04:19 +02:00
|
|
|
|
2017-07-17 10:26:19 +02:00
|
|
|
return( ret );
|
|
|
|
}
|
2017-08-14 18:04:19 +02:00
|
|
|
#else
|
|
|
|
(void) ret;
|
|
|
|
#endif
|
2017-07-17 10:26:19 +02:00
|
|
|
|
|
|
|
signature_is_good = ret == 0;
|
|
|
|
if( top && ! signature_is_good )
|
2017-07-03 19:26:25 +02:00
|
|
|
continue;
|
2017-07-03 18:30:43 +02:00
|
|
|
|
2017-08-08 18:09:14 +02:00
|
|
|
/* optional time check */
|
2019-02-24 18:47:46 +01:00
|
|
|
if( !parent_valid )
|
2017-06-29 12:55:27 +02:00
|
|
|
{
|
2019-06-10 12:12:33 +02:00
|
|
|
#if defined(MBEDTLS_HAVE_TIME_DATE)
|
2017-07-14 12:04:14 +02:00
|
|
|
if( fallback_parent == NULL )
|
|
|
|
{
|
2019-02-25 15:46:49 +01:00
|
|
|
fallback_parent = parent_crt;
|
2018-07-02 12:33:14 +02:00
|
|
|
fallback_signature_is_good = signature_is_good;
|
2017-07-14 12:04:14 +02:00
|
|
|
}
|
2019-06-10 12:12:33 +02:00
|
|
|
#endif /* MBEDTLS_HAVE_TIME_DATE */
|
2017-06-29 12:55:27 +02:00
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-06-29 12:27:23 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-02-25 15:46:49 +01:00
|
|
|
if( parent_crt != NULL )
|
2017-07-14 12:04:14 +02:00
|
|
|
{
|
2019-02-25 15:46:49 +01:00
|
|
|
*r_parent = parent_crt;
|
2017-07-17 10:26:19 +02:00
|
|
|
*r_signature_is_good = signature_is_good;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-06-10 12:12:33 +02:00
|
|
|
#if defined(MBEDTLS_HAVE_TIME_DATE)
|
2017-07-17 10:26:19 +02:00
|
|
|
*r_parent = fallback_parent;
|
2018-07-02 12:33:14 +02:00
|
|
|
*r_signature_is_good = fallback_signature_is_good;
|
2019-06-10 12:12:33 +02:00
|
|
|
#else /* MBEDTLS_HAVE_TIME_DATE */
|
|
|
|
*r_parent = NULL;
|
|
|
|
#endif /* !MBEDTLS_HAVE_TIME_DATE */
|
2017-07-14 12:04:14 +02:00
|
|
|
}
|
2017-06-29 12:55:27 +02:00
|
|
|
|
2017-07-17 10:26:19 +02:00
|
|
|
return( 0 );
|
2017-06-29 12:27:23 +02:00
|
|
|
}
|
|
|
|
|
2017-07-04 01:01:39 +02:00
|
|
|
/*
|
|
|
|
* Find a parent in trusted CAs or the provided chain, or return NULL.
|
|
|
|
*
|
|
|
|
* Searches in trusted CAs first, and return the first suitable parent found
|
|
|
|
* (see find_parent_in() for definition of suitable).
|
2017-08-17 10:52:20 +02:00
|
|
|
*
|
|
|
|
* Arguments:
|
2018-03-07 10:00:57 +01:00
|
|
|
* - [in] child: certificate for which we're looking for a parent, followed
|
|
|
|
* by a chain of possible intermediates
|
2018-06-12 12:40:54 +02:00
|
|
|
* - [in] trust_ca: list of locally trusted certificates
|
|
|
|
* - [out] parent: parent found (or NULL)
|
|
|
|
* - [out] parent_is_trusted: 1 if returned `parent` is trusted, or 0
|
|
|
|
* - [out] signature_is_good: 1 if child signature by parent is valid, or 0
|
|
|
|
* - [in] path_cnt: number of links in the chain so far (EE -> ... -> child)
|
|
|
|
* - [in] self_cnt: number of self-signed certs in the chain so far
|
2018-03-07 10:00:57 +01:00
|
|
|
* (will always be no greater than path_cnt)
|
2018-06-12 12:40:54 +02:00
|
|
|
* - [in-out] rs_ctx: context for restarting operations
|
2018-03-07 10:00:57 +01:00
|
|
|
*
|
|
|
|
* Return value:
|
2018-06-12 12:40:54 +02:00
|
|
|
* - 0 on success
|
|
|
|
* - MBEDTLS_ERR_ECP_IN_PROGRESS otherwise
|
2017-07-04 01:01:39 +02:00
|
|
|
*/
|
2017-07-17 10:26:19 +02:00
|
|
|
static int x509_crt_find_parent(
|
2019-02-25 14:50:41 +01:00
|
|
|
mbedtls_x509_crt_sig_info const *child_sig,
|
2019-02-25 15:58:22 +01:00
|
|
|
mbedtls_x509_crt *rest,
|
2017-07-17 10:26:19 +02:00
|
|
|
mbedtls_x509_crt *trust_ca,
|
|
|
|
mbedtls_x509_crt **parent,
|
|
|
|
int *parent_is_trusted,
|
|
|
|
int *signature_is_good,
|
2017-08-28 13:25:55 +02:00
|
|
|
unsigned path_cnt,
|
|
|
|
unsigned self_cnt,
|
2017-07-17 10:26:19 +02:00
|
|
|
mbedtls_x509_crt_restart_ctx *rs_ctx )
|
2017-07-04 01:01:39 +02:00
|
|
|
{
|
2017-07-17 10:26:19 +02:00
|
|
|
int ret;
|
2017-08-14 16:11:43 +02:00
|
|
|
mbedtls_x509_crt *search_list;
|
2017-07-04 01:01:39 +02:00
|
|
|
|
|
|
|
*parent_is_trusted = 1;
|
2017-08-14 16:11:43 +02:00
|
|
|
|
2017-08-14 18:04:19 +02:00
|
|
|
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
2017-08-23 11:20:48 +02:00
|
|
|
/* restore then clear saved state if we have some stored */
|
|
|
|
if( rs_ctx != NULL && rs_ctx->parent_is_trusted != -1 )
|
|
|
|
{
|
2017-08-14 18:04:19 +02:00
|
|
|
*parent_is_trusted = rs_ctx->parent_is_trusted;
|
2017-08-23 11:20:48 +02:00
|
|
|
rs_ctx->parent_is_trusted = -1;
|
|
|
|
}
|
2017-08-14 18:04:19 +02:00
|
|
|
#endif
|
|
|
|
|
2017-08-14 16:11:43 +02:00
|
|
|
while( 1 ) {
|
2019-02-25 15:58:22 +01:00
|
|
|
search_list = *parent_is_trusted ? trust_ca : rest;
|
2017-08-14 16:11:43 +02:00
|
|
|
|
2019-02-25 14:50:41 +01:00
|
|
|
ret = x509_crt_find_parent_in( child_sig, search_list,
|
2017-08-14 16:11:43 +02:00
|
|
|
parent, signature_is_good,
|
|
|
|
*parent_is_trusted,
|
|
|
|
path_cnt, self_cnt, rs_ctx );
|
2017-07-04 01:01:39 +02:00
|
|
|
|
2017-07-17 10:26:19 +02:00
|
|
|
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
2017-08-14 18:04:19 +02:00
|
|
|
if( rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
|
|
|
|
{
|
|
|
|
/* save state */
|
|
|
|
rs_ctx->parent_is_trusted = *parent_is_trusted;
|
2017-08-14 16:11:43 +02:00
|
|
|
return( ret );
|
|
|
|
}
|
2017-08-14 18:04:19 +02:00
|
|
|
#else
|
|
|
|
(void) ret;
|
|
|
|
#endif
|
2017-07-17 10:26:19 +02:00
|
|
|
|
2017-08-14 16:11:43 +02:00
|
|
|
/* stop here if found or already in second iteration */
|
|
|
|
if( *parent != NULL || *parent_is_trusted == 0 )
|
|
|
|
break;
|
2017-07-04 01:01:39 +02:00
|
|
|
|
2017-08-14 16:11:43 +02:00
|
|
|
/* prepare second iteration */
|
|
|
|
*parent_is_trusted = 0;
|
|
|
|
}
|
2017-07-17 10:26:19 +02:00
|
|
|
|
2017-08-14 16:11:43 +02:00
|
|
|
/* extra precaution against mistakes in the caller */
|
2018-10-31 16:49:20 +01:00
|
|
|
if( *parent == NULL )
|
2017-08-14 16:11:43 +02:00
|
|
|
{
|
2018-10-16 11:27:23 +02:00
|
|
|
*parent_is_trusted = 0;
|
|
|
|
*signature_is_good = 0;
|
2017-07-17 10:26:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return( 0 );
|
2017-07-04 01:01:39 +02:00
|
|
|
}
|
|
|
|
|
2017-07-04 00:49:31 +02:00
|
|
|
/*
|
|
|
|
* Check if an end-entity certificate is locally trusted
|
|
|
|
*
|
|
|
|
* Currently we require such certificates to be self-signed (actually only
|
|
|
|
* check for self-issued as self-signatures are not checked)
|
|
|
|
*/
|
|
|
|
static int x509_crt_check_ee_locally_trusted(
|
2019-02-25 15:58:22 +01:00
|
|
|
mbedtls_x509_crt_frame const *crt,
|
|
|
|
mbedtls_x509_crt const *trust_ca )
|
2017-07-04 00:49:31 +02:00
|
|
|
{
|
2019-02-25 15:58:22 +01:00
|
|
|
mbedtls_x509_crt const *cur;
|
2017-07-04 00:49:31 +02:00
|
|
|
|
|
|
|
/* look for an exact match with trusted cert */
|
|
|
|
for( cur = trust_ca; cur != NULL; cur = cur->next )
|
|
|
|
{
|
|
|
|
if( crt->raw.len == cur->raw.len &&
|
|
|
|
memcmp( crt->raw.p, cur->raw.p, crt->raw.len ) == 0 )
|
|
|
|
{
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* too bad */
|
|
|
|
return( -1 );
|
|
|
|
}
|
|
|
|
|
2017-06-29 10:45:25 +02:00
|
|
|
/*
|
2017-07-05 16:43:44 +02:00
|
|
|
* Build and verify a certificate chain
|
2017-06-29 10:45:25 +02:00
|
|
|
*
|
2017-07-05 16:43:44 +02:00
|
|
|
* Given a peer-provided list of certificates EE, C1, ..., Cn and
|
|
|
|
* a list of trusted certs R1, ... Rp, try to build and verify a chain
|
2017-08-08 18:09:14 +02:00
|
|
|
* EE, Ci1, ... Ciq [, Rj]
|
2017-07-05 16:43:44 +02:00
|
|
|
* such that every cert in the chain is a child of the next one,
|
|
|
|
* jumping to a trusted root as early as possible.
|
2017-07-04 00:33:39 +02:00
|
|
|
*
|
2017-07-05 16:43:44 +02:00
|
|
|
* Verify that chain and return it with flags for all issues found.
|
|
|
|
*
|
|
|
|
* Special cases:
|
|
|
|
* - EE == Rj -> return a one-element list containing it
|
|
|
|
* - EE, Ci1, ..., Ciq cannot be continued with a trusted root
|
|
|
|
* -> return that chain with NOT_TRUSTED set on Ciq
|
2017-07-04 00:33:39 +02:00
|
|
|
*
|
2017-07-14 11:05:59 +02:00
|
|
|
* Tests for (aspects of) this function should include at least:
|
|
|
|
* - trusted EE
|
|
|
|
* - EE -> trusted root
|
2019-01-23 15:24:37 +01:00
|
|
|
* - EE -> intermediate CA -> trusted root
|
2017-07-14 11:05:59 +02:00
|
|
|
* - if relevant: EE untrusted
|
|
|
|
* - if relevant: EE -> intermediate, untrusted
|
|
|
|
* with the aspect under test checked at each relevant level (EE, int, root).
|
|
|
|
* For some aspects longer chains are required, but usually length 2 is
|
|
|
|
* enough (but length 1 is not in general).
|
|
|
|
*
|
2017-07-04 00:33:39 +02:00
|
|
|
* Arguments:
|
2017-07-05 17:05:03 +02:00
|
|
|
* - [in] crt: the cert list EE, C1, ..., Cn
|
|
|
|
* - [in] trust_ca: the trusted list R1, ..., Rp
|
|
|
|
* - [in] ca_crl, profile: as in verify_with_profile()
|
2017-08-14 17:17:14 +02:00
|
|
|
* - [out] ver_chain: the built and verified chain
|
2017-08-23 11:23:59 +02:00
|
|
|
* Only valid when return value is 0, may contain garbage otherwise!
|
|
|
|
* Restart note: need not be the same when calling again to resume.
|
2017-08-17 10:52:20 +02:00
|
|
|
* - [in-out] rs_ctx: context for restarting operations
|
2017-07-05 16:43:44 +02:00
|
|
|
*
|
|
|
|
* Return value:
|
|
|
|
* - non-zero if the chain could not be fully built and examined
|
|
|
|
* - 0 is the chain was successfully built and examined,
|
|
|
|
* even if it was found to be invalid
|
2017-06-29 10:45:25 +02:00
|
|
|
*/
|
2017-07-04 00:33:39 +02:00
|
|
|
static int x509_crt_verify_chain(
|
2017-07-05 17:05:03 +02:00
|
|
|
mbedtls_x509_crt *crt,
|
|
|
|
mbedtls_x509_crt *trust_ca,
|
|
|
|
mbedtls_x509_crl *ca_crl,
|
2015-06-15 10:39:46 +02:00
|
|
|
const mbedtls_x509_crt_profile *profile,
|
2017-08-14 17:17:14 +02:00
|
|
|
mbedtls_x509_crt_verify_chain *ver_chain,
|
2017-07-17 10:26:19 +02:00
|
|
|
mbedtls_x509_crt_restart_ctx *rs_ctx )
|
2012-09-28 09:10:55 +02:00
|
|
|
{
|
2017-08-23 11:23:59 +02:00
|
|
|
/* Don't initialize any of those variables here, so that the compiler can
|
|
|
|
* catch potential issues with jumping ahead when restarting */
|
2017-07-17 10:26:19 +02:00
|
|
|
int ret;
|
2017-07-05 16:43:44 +02:00
|
|
|
uint32_t *flags;
|
2017-08-14 17:17:14 +02:00
|
|
|
mbedtls_x509_crt_verify_chain_item *cur;
|
2019-02-25 15:58:22 +01:00
|
|
|
mbedtls_x509_crt *child_crt;
|
2019-02-25 19:13:46 +01:00
|
|
|
mbedtls_x509_crt *parent_crt;
|
2017-08-14 18:04:19 +02:00
|
|
|
int parent_is_trusted;
|
|
|
|
int child_is_trusted;
|
|
|
|
int signature_is_good;
|
2017-08-28 13:25:55 +02:00
|
|
|
unsigned self_cnt;
|
2017-08-14 18:04:19 +02:00
|
|
|
|
|
|
|
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
|
|
|
/* resume if we had an operation in progress */
|
2017-08-23 12:32:19 +02:00
|
|
|
if( rs_ctx != NULL && rs_ctx->in_progress == x509_crt_rs_find_parent )
|
2017-08-14 18:04:19 +02:00
|
|
|
{
|
2017-08-23 11:20:48 +02:00
|
|
|
/* restore saved state */
|
2017-08-23 11:23:59 +02:00
|
|
|
*ver_chain = rs_ctx->ver_chain; /* struct copy */
|
2017-08-23 12:32:19 +02:00
|
|
|
self_cnt = rs_ctx->self_cnt;
|
2017-08-14 18:04:19 +02:00
|
|
|
|
2017-08-23 12:32:19 +02:00
|
|
|
/* restore derived state */
|
2017-08-14 18:04:19 +02:00
|
|
|
cur = &ver_chain->items[ver_chain->len - 1];
|
2019-02-25 15:58:22 +01:00
|
|
|
child_crt = cur->crt;
|
|
|
|
|
|
|
|
child_is_trusted = 0;
|
2017-08-14 18:04:19 +02:00
|
|
|
goto find_parent;
|
|
|
|
}
|
|
|
|
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
|
2017-07-03 21:25:10 +02:00
|
|
|
|
2019-02-25 15:58:22 +01:00
|
|
|
child_crt = crt;
|
2017-08-14 18:04:19 +02:00
|
|
|
self_cnt = 0;
|
|
|
|
parent_is_trusted = 0;
|
|
|
|
child_is_trusted = 0;
|
2017-07-05 16:43:44 +02:00
|
|
|
|
2017-07-05 17:05:03 +02:00
|
|
|
while( 1 ) {
|
2019-02-25 14:50:41 +01:00
|
|
|
#if defined(MBEDTLS_X509_CRL_PARSE_C)
|
|
|
|
mbedtls_x509_buf_raw child_serial;
|
|
|
|
#endif /* MBEDTLS_X509_CRL_PARSE_C */
|
|
|
|
int self_issued;
|
2019-02-25 15:58:22 +01:00
|
|
|
|
2017-07-05 17:05:03 +02:00
|
|
|
/* Add certificate to the verification chain */
|
2017-08-14 17:17:14 +02:00
|
|
|
cur = &ver_chain->items[ver_chain->len];
|
2019-02-25 15:58:22 +01:00
|
|
|
cur->crt = child_crt;
|
2017-08-23 10:55:41 +02:00
|
|
|
cur->flags = 0;
|
2017-08-14 17:17:14 +02:00
|
|
|
ver_chain->len++;
|
2019-02-22 18:56:43 +01:00
|
|
|
|
|
|
|
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
|
|
|
find_parent:
|
|
|
|
#endif
|
|
|
|
|
2017-08-23 10:55:41 +02:00
|
|
|
flags = &cur->flags;
|
2017-07-03 21:39:21 +02:00
|
|
|
|
2019-02-25 14:50:41 +01:00
|
|
|
{
|
|
|
|
mbedtls_x509_crt_sig_info child_sig;
|
|
|
|
{
|
2019-05-20 17:26:34 +02:00
|
|
|
mbedtls_x509_crt_frame const *child;
|
2019-02-25 14:50:41 +01:00
|
|
|
|
2019-02-25 14:50:14 +01:00
|
|
|
ret = mbedtls_x509_crt_frame_acquire( child_crt, &child );
|
2019-02-25 14:50:41 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
return( MBEDTLS_ERR_X509_FATAL_ERROR );
|
|
|
|
|
2019-06-25 10:39:21 +02:00
|
|
|
#if !defined(MBEDTLS_X509_CRT_REMOVE_TIME)
|
2019-02-25 14:50:41 +01:00
|
|
|
/* Check time-validity (all certificates) */
|
|
|
|
if( mbedtls_x509_time_is_past( &child->valid_to ) )
|
|
|
|
*flags |= MBEDTLS_X509_BADCERT_EXPIRED;
|
|
|
|
if( mbedtls_x509_time_is_future( &child->valid_from ) )
|
|
|
|
*flags |= MBEDTLS_X509_BADCERT_FUTURE;
|
2019-06-25 10:39:21 +02:00
|
|
|
#endif /* !MBEDTLS_X509_CRT_REMOVE_TIME */
|
2019-02-25 14:50:41 +01:00
|
|
|
|
|
|
|
/* Stop here for trusted roots (but not for trusted EE certs) */
|
|
|
|
if( child_is_trusted )
|
|
|
|
{
|
2019-03-05 14:50:56 +01:00
|
|
|
mbedtls_x509_crt_frame_release( child_crt );
|
2019-02-25 14:50:41 +01:00
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
self_issued = 0;
|
|
|
|
if( mbedtls_x509_name_cmp_raw( &child->issuer_raw,
|
|
|
|
&child->subject_raw,
|
|
|
|
NULL, NULL ) == 0 )
|
|
|
|
{
|
|
|
|
self_issued = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check signature algorithm: MD & PK algs */
|
|
|
|
if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 )
|
|
|
|
*flags |= MBEDTLS_X509_BADCERT_BAD_MD;
|
|
|
|
|
|
|
|
if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 )
|
|
|
|
*flags |= MBEDTLS_X509_BADCERT_BAD_PK;
|
|
|
|
|
|
|
|
/* Special case: EE certs that are locally trusted */
|
|
|
|
if( ver_chain->len == 1 && self_issued &&
|
|
|
|
x509_crt_check_ee_locally_trusted( child, trust_ca ) == 0 )
|
|
|
|
{
|
2019-03-05 14:50:56 +01:00
|
|
|
mbedtls_x509_crt_frame_release( child_crt );
|
2019-02-25 14:50:41 +01:00
|
|
|
return( 0 );
|
|
|
|
}
|
2017-07-03 21:39:21 +02:00
|
|
|
|
2019-02-25 14:50:41 +01:00
|
|
|
#if defined(MBEDTLS_X509_CRL_PARSE_C)
|
|
|
|
child_serial = child->serial;
|
|
|
|
#endif /* MBEDTLS_X509_CRL_PARSE_C */
|
2017-07-04 00:00:24 +02:00
|
|
|
|
2019-02-25 14:50:41 +01:00
|
|
|
ret = x509_crt_get_sig_info( child, &child_sig );
|
2019-03-05 14:50:56 +01:00
|
|
|
mbedtls_x509_crt_frame_release( child_crt );
|
2017-07-03 21:39:21 +02:00
|
|
|
|
2019-02-25 14:50:41 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
return( MBEDTLS_ERR_X509_FATAL_ERROR );
|
|
|
|
}
|
2017-07-03 21:39:21 +02:00
|
|
|
|
2019-02-25 14:50:41 +01:00
|
|
|
/* Look for a parent in trusted CAs or up the chain */
|
|
|
|
ret = x509_crt_find_parent( &child_sig, child_crt->next,
|
2019-02-25 19:13:46 +01:00
|
|
|
trust_ca, &parent_crt,
|
2019-02-25 14:50:41 +01:00
|
|
|
&parent_is_trusted, &signature_is_good,
|
|
|
|
ver_chain->len - 1, self_cnt, rs_ctx );
|
2017-07-04 00:49:31 +02:00
|
|
|
|
2019-02-25 14:50:41 +01:00
|
|
|
x509_crt_free_sig_info( &child_sig );
|
2017-07-05 17:05:03 +02:00
|
|
|
}
|
2017-07-03 21:25:10 +02:00
|
|
|
|
2017-07-17 10:26:19 +02:00
|
|
|
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
2017-08-14 18:04:19 +02:00
|
|
|
if( rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
|
|
|
|
{
|
|
|
|
/* save state */
|
2017-08-23 12:32:19 +02:00
|
|
|
rs_ctx->in_progress = x509_crt_rs_find_parent;
|
2017-08-14 18:04:19 +02:00
|
|
|
rs_ctx->self_cnt = self_cnt;
|
2017-08-23 11:23:59 +02:00
|
|
|
rs_ctx->ver_chain = *ver_chain; /* struct copy */
|
2019-02-25 14:50:41 +01:00
|
|
|
return( ret );
|
2017-07-17 10:26:19 +02:00
|
|
|
}
|
2017-08-14 18:04:19 +02:00
|
|
|
#else
|
|
|
|
(void) ret;
|
|
|
|
#endif
|
2012-09-28 09:10:55 +02:00
|
|
|
|
2017-07-05 17:05:03 +02:00
|
|
|
/* No parent? We're done here */
|
2019-02-25 19:13:46 +01:00
|
|
|
if( parent_crt == NULL )
|
2017-07-05 17:05:03 +02:00
|
|
|
{
|
|
|
|
*flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
|
2019-02-25 14:50:41 +01:00
|
|
|
return( 0 );
|
2017-07-05 17:05:03 +02:00
|
|
|
}
|
2012-09-28 09:10:55 +02:00
|
|
|
|
2017-07-05 17:05:03 +02:00
|
|
|
/* Count intermediate self-issued (not necessarily self-signed) certs.
|
|
|
|
* These can occur with some strategies for key rollover, see [SIRO],
|
|
|
|
* and should be excluded from max_pathlen checks. */
|
2019-02-25 14:50:41 +01:00
|
|
|
if( ver_chain->len != 1 && self_issued )
|
2017-07-05 17:05:03 +02:00
|
|
|
self_cnt++;
|
2014-11-20 16:34:20 +01:00
|
|
|
|
2017-07-05 17:05:03 +02:00
|
|
|
/* path_cnt is 0 for the first intermediate CA,
|
|
|
|
* and if parent is trusted it's not an intermediate CA */
|
|
|
|
if( ! parent_is_trusted &&
|
2017-08-14 17:17:14 +02:00
|
|
|
ver_chain->len > MBEDTLS_X509_MAX_INTERMEDIATE_CA )
|
2017-07-05 17:05:03 +02:00
|
|
|
{
|
|
|
|
/* return immediately to avoid overflow the chain array */
|
2019-02-25 14:50:41 +01:00
|
|
|
return( MBEDTLS_ERR_X509_FATAL_ERROR );
|
2017-07-05 17:05:03 +02:00
|
|
|
}
|
|
|
|
|
2017-08-17 10:52:20 +02:00
|
|
|
/* signature was checked while searching parent */
|
2017-07-14 12:04:14 +02:00
|
|
|
if( ! signature_is_good )
|
2017-07-05 17:05:03 +02:00
|
|
|
*flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
|
2012-09-28 09:10:55 +02:00
|
|
|
|
2019-02-25 19:13:46 +01:00
|
|
|
{
|
|
|
|
mbedtls_pk_context *parent_pk;
|
2019-02-25 14:50:14 +01:00
|
|
|
ret = mbedtls_x509_crt_pk_acquire( parent_crt, &parent_pk );
|
2019-02-25 19:13:46 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
return( MBEDTLS_ERR_X509_FATAL_ERROR );
|
|
|
|
|
|
|
|
/* check size of signing key */
|
|
|
|
if( x509_profile_check_key( profile, parent_pk ) != 0 )
|
|
|
|
*flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
|
|
|
|
|
2019-03-05 14:50:56 +01:00
|
|
|
mbedtls_x509_crt_pk_release( parent_crt );
|
2019-02-25 19:13:46 +01:00
|
|
|
}
|
2012-09-28 09:10:55 +02:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
#if defined(MBEDTLS_X509_CRL_PARSE_C)
|
2017-07-05 17:05:03 +02:00
|
|
|
/* Check trusted CA's CRL for the given crt */
|
2019-02-25 14:50:41 +01:00
|
|
|
*flags |= x509_crt_verifycrl( child_serial.p,
|
|
|
|
child_serial.len,
|
2019-02-25 19:13:46 +01:00
|
|
|
parent_crt, ca_crl, profile );
|
2017-07-05 17:05:03 +02:00
|
|
|
#else
|
|
|
|
(void) ca_crl;
|
2013-09-16 13:49:26 +02:00
|
|
|
#endif
|
2012-09-28 09:10:55 +02:00
|
|
|
|
2017-07-05 17:05:03 +02:00
|
|
|
/* prepare for next iteration */
|
2019-02-25 19:13:46 +01:00
|
|
|
child_crt = parent_crt;
|
|
|
|
parent_crt = NULL;
|
2017-07-05 17:05:03 +02:00
|
|
|
child_is_trusted = parent_is_trusted;
|
2017-07-14 12:04:14 +02:00
|
|
|
signature_is_good = 0;
|
2017-07-05 17:05:03 +02:00
|
|
|
}
|
2012-09-28 09:10:55 +02:00
|
|
|
}
|
|
|
|
|
2017-07-04 01:31:59 +02:00
|
|
|
/*
|
|
|
|
* Check for CN match
|
|
|
|
*/
|
2019-02-21 14:10:55 +01:00
|
|
|
static int x509_crt_check_cn( unsigned char const *buf,
|
|
|
|
size_t buflen,
|
|
|
|
const char *cn,
|
|
|
|
size_t cn_len )
|
2017-07-04 01:31:59 +02:00
|
|
|
{
|
2019-02-21 14:10:55 +01:00
|
|
|
/* Try exact match */
|
2019-02-22 12:46:06 +01:00
|
|
|
if( mbedtls_x509_memcasecmp( cn, buf, buflen, cn_len ) == 0 )
|
2017-07-04 01:31:59 +02:00
|
|
|
return( 0 );
|
|
|
|
|
|
|
|
/* try wildcard match */
|
2019-02-21 14:10:55 +01:00
|
|
|
if( x509_check_wildcard( cn, cn_len, buf, buflen ) == 0 )
|
2017-07-04 01:31:59 +02:00
|
|
|
{
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
return( -1 );
|
|
|
|
}
|
|
|
|
|
2019-02-21 12:50:44 +01:00
|
|
|
/* Returns 1 on a match and 0 on a mismatch.
|
|
|
|
* This is because this function is used as a callback for
|
|
|
|
* mbedtls_x509_name_cmp_raw(), which continues the name
|
|
|
|
* traversal as long as the callback returns 0. */
|
|
|
|
static int x509_crt_check_name( void *ctx,
|
|
|
|
mbedtls_x509_buf *oid,
|
2019-02-23 11:20:14 +01:00
|
|
|
mbedtls_x509_buf *val,
|
|
|
|
int next_merged )
|
2019-02-21 12:50:44 +01:00
|
|
|
{
|
|
|
|
char const *cn = (char const*) ctx;
|
|
|
|
size_t cn_len = strlen( cn );
|
2019-02-23 11:20:14 +01:00
|
|
|
((void) next_merged);
|
2019-02-21 12:50:44 +01:00
|
|
|
|
|
|
|
if( MBEDTLS_OID_CMP( MBEDTLS_OID_AT_CN, oid ) == 0 &&
|
2019-02-21 14:10:55 +01:00
|
|
|
x509_crt_check_cn( val->p, val->len, cn, cn_len ) == 0 )
|
2019-02-21 12:50:44 +01:00
|
|
|
{
|
|
|
|
return( 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
2019-02-21 14:36:59 +01:00
|
|
|
/* Returns 1 on a match and 0 on a mismatch.
|
|
|
|
* This is because this function is used as a callback for
|
|
|
|
* mbedtls_asn1_traverse_sequence_of(), which continues the
|
|
|
|
* traversal as long as the callback returns 0. */
|
|
|
|
static int x509_crt_subject_alt_check_name( void *ctx,
|
|
|
|
int tag,
|
|
|
|
unsigned char *data,
|
|
|
|
size_t data_len )
|
|
|
|
{
|
|
|
|
char const *cn = (char const*) ctx;
|
|
|
|
size_t cn_len = strlen( cn );
|
2019-02-21 22:13:21 +01:00
|
|
|
((void) tag);
|
2019-02-21 14:36:59 +01:00
|
|
|
|
|
|
|
if( x509_crt_check_cn( data, data_len, cn, cn_len ) == 0 )
|
|
|
|
return( 1 );
|
|
|
|
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
2017-07-04 01:13:44 +02:00
|
|
|
/*
|
|
|
|
* Verify the requested CN - only call this if cn is not NULL!
|
|
|
|
*/
|
2019-02-25 19:14:40 +01:00
|
|
|
static int x509_crt_verify_name( const mbedtls_x509_crt *crt,
|
|
|
|
const char *cn,
|
|
|
|
uint32_t *flags )
|
2017-07-04 01:13:44 +02:00
|
|
|
{
|
2019-02-21 14:36:59 +01:00
|
|
|
int ret;
|
2019-05-20 17:26:34 +02:00
|
|
|
mbedtls_x509_crt_frame const *frame;
|
2017-07-04 01:13:44 +02:00
|
|
|
|
2019-02-25 14:50:14 +01:00
|
|
|
ret = mbedtls_x509_crt_frame_acquire( crt, &frame );
|
2019-02-25 19:14:40 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
return( MBEDTLS_ERR_X509_FATAL_ERROR );
|
|
|
|
|
|
|
|
if( frame->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME )
|
2017-07-04 01:13:44 +02:00
|
|
|
{
|
2019-02-21 22:13:21 +01:00
|
|
|
unsigned char *p =
|
2019-02-25 19:14:40 +01:00
|
|
|
frame->subject_alt_raw.p;
|
2019-02-21 14:36:59 +01:00
|
|
|
const unsigned char *end =
|
2019-02-25 19:14:40 +01:00
|
|
|
frame->subject_alt_raw.p + frame->subject_alt_raw.len;
|
2017-07-04 01:13:44 +02:00
|
|
|
|
2019-02-21 22:13:21 +01:00
|
|
|
ret = mbedtls_asn1_traverse_sequence_of( &p, end,
|
|
|
|
MBEDTLS_ASN1_TAG_CLASS_MASK,
|
|
|
|
MBEDTLS_ASN1_CONTEXT_SPECIFIC,
|
|
|
|
MBEDTLS_ASN1_TAG_VALUE_MASK,
|
|
|
|
2 /* SubjectAlt DNS */,
|
|
|
|
x509_crt_subject_alt_check_name,
|
2019-05-29 15:41:44 +02:00
|
|
|
(void *) cn );
|
2017-07-04 01:13:44 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-02-25 19:14:40 +01:00
|
|
|
ret = mbedtls_x509_name_cmp_raw( &frame->subject_raw,
|
|
|
|
&frame->subject_raw,
|
2019-05-29 15:41:44 +02:00
|
|
|
x509_crt_check_name, (void *) cn );
|
2017-07-04 01:13:44 +02:00
|
|
|
}
|
2019-02-21 14:36:59 +01:00
|
|
|
|
2019-03-05 14:50:56 +01:00
|
|
|
mbedtls_x509_crt_frame_release( crt );
|
2019-02-25 19:14:40 +01:00
|
|
|
|
|
|
|
/* x509_crt_check_name() and x509_crt_subject_alt_check_name()
|
|
|
|
* return 1 when finding a name component matching `cn`. */
|
|
|
|
if( ret == 1 )
|
|
|
|
return( 0 );
|
|
|
|
|
|
|
|
if( ret != 0 )
|
|
|
|
ret = MBEDTLS_ERR_X509_FATAL_ERROR;
|
|
|
|
|
|
|
|
*flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
|
|
|
|
return( ret );
|
2017-07-04 01:13:44 +02:00
|
|
|
}
|
|
|
|
|
2017-07-05 17:18:42 +02:00
|
|
|
/*
|
|
|
|
* Merge the flags for all certs in the chain, after calling callback
|
|
|
|
*/
|
|
|
|
static int x509_crt_merge_flags_with_cb(
|
|
|
|
uint32_t *flags,
|
2017-08-14 17:17:14 +02:00
|
|
|
const mbedtls_x509_crt_verify_chain *ver_chain,
|
2017-07-05 17:18:42 +02:00
|
|
|
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
|
|
|
|
void *p_vrfy )
|
|
|
|
{
|
|
|
|
int ret;
|
2017-08-28 13:25:55 +02:00
|
|
|
unsigned i;
|
2017-07-05 17:18:42 +02:00
|
|
|
uint32_t cur_flags;
|
2017-08-14 17:17:14 +02:00
|
|
|
const mbedtls_x509_crt_verify_chain_item *cur;
|
2017-07-05 17:18:42 +02:00
|
|
|
|
2017-08-14 17:17:14 +02:00
|
|
|
for( i = ver_chain->len; i != 0; --i )
|
2017-07-05 17:18:42 +02:00
|
|
|
{
|
2017-08-14 17:17:14 +02:00
|
|
|
cur = &ver_chain->items[i-1];
|
|
|
|
cur_flags = cur->flags;
|
2017-07-05 17:18:42 +02:00
|
|
|
|
|
|
|
if( NULL != f_vrfy )
|
2017-08-28 13:25:55 +02:00
|
|
|
if( ( ret = f_vrfy( p_vrfy, cur->crt, (int) i-1, &cur_flags ) ) != 0 )
|
2017-07-05 17:18:42 +02:00
|
|
|
return( ret );
|
|
|
|
|
|
|
|
*flags |= cur_flags;
|
|
|
|
}
|
|
|
|
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
2009-01-03 22:22:43 +01:00
|
|
|
/*
|
2017-07-11 11:02:20 +02:00
|
|
|
* Verify the certificate validity (default profile, not restartable)
|
2009-01-03 22:22:43 +01:00
|
|
|
*/
|
2015-04-08 12:49:31 +02:00
|
|
|
int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt,
|
|
|
|
mbedtls_x509_crt *trust_ca,
|
|
|
|
mbedtls_x509_crl *ca_crl,
|
2015-05-11 19:54:43 +02:00
|
|
|
const char *cn, uint32_t *flags,
|
|
|
|
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
|
2013-09-18 13:46:23 +02:00
|
|
|
void *p_vrfy )
|
2015-06-15 10:39:46 +02:00
|
|
|
{
|
2017-07-11 11:02:20 +02:00
|
|
|
return( mbedtls_x509_crt_verify_restartable( crt, trust_ca, ca_crl,
|
|
|
|
&mbedtls_x509_crt_profile_default, cn, flags,
|
|
|
|
f_vrfy, p_vrfy, NULL ) );
|
2015-06-15 10:39:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2017-07-11 11:02:20 +02:00
|
|
|
* Verify the certificate validity (user-chosen profile, not restartable)
|
|
|
|
*/
|
|
|
|
int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
|
|
|
|
mbedtls_x509_crt *trust_ca,
|
|
|
|
mbedtls_x509_crl *ca_crl,
|
|
|
|
const mbedtls_x509_crt_profile *profile,
|
|
|
|
const char *cn, uint32_t *flags,
|
|
|
|
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
|
|
|
|
void *p_vrfy )
|
|
|
|
{
|
|
|
|
return( mbedtls_x509_crt_verify_restartable( crt, trust_ca, ca_crl,
|
|
|
|
profile, cn, flags, f_vrfy, p_vrfy, NULL ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Verify the certificate validity, with profile, restartable version
|
2017-06-29 10:45:25 +02:00
|
|
|
*
|
2017-07-12 12:23:06 +02:00
|
|
|
* This function:
|
|
|
|
* - checks the requested CN (if any)
|
|
|
|
* - checks the type and size of the EE cert's key,
|
|
|
|
* as that isn't done as part of chain building/verification currently
|
|
|
|
* - builds and verifies the chain
|
|
|
|
* - then calls the callback and merges the flags
|
2015-06-15 10:39:46 +02:00
|
|
|
*/
|
2017-07-11 11:02:20 +02:00
|
|
|
int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt,
|
2015-06-15 10:39:46 +02:00
|
|
|
mbedtls_x509_crt *trust_ca,
|
|
|
|
mbedtls_x509_crl *ca_crl,
|
|
|
|
const mbedtls_x509_crt_profile *profile,
|
|
|
|
const char *cn, uint32_t *flags,
|
|
|
|
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
|
2017-07-11 11:02:20 +02:00
|
|
|
void *p_vrfy,
|
|
|
|
mbedtls_x509_crt_restart_ctx *rs_ctx )
|
2009-01-03 22:22:43 +01:00
|
|
|
{
|
2012-09-28 09:10:55 +02:00
|
|
|
int ret;
|
2017-08-14 17:17:14 +02:00
|
|
|
mbedtls_x509_crt_verify_chain ver_chain;
|
2017-08-23 10:55:41 +02:00
|
|
|
uint32_t ee_flags;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2009-05-03 12:18:48 +02:00
|
|
|
*flags = 0;
|
2017-08-23 10:55:41 +02:00
|
|
|
ee_flags = 0;
|
|
|
|
x509_crt_verify_chain_reset( &ver_chain );
|
2009-05-03 12:18:48 +02:00
|
|
|
|
2017-06-22 12:19:27 +02:00
|
|
|
if( profile == NULL )
|
|
|
|
{
|
|
|
|
ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
2017-07-04 01:13:44 +02:00
|
|
|
/* check name if requested */
|
2009-01-03 22:22:43 +01:00
|
|
|
if( cn != NULL )
|
2019-02-25 19:15:33 +01:00
|
|
|
{
|
|
|
|
ret = x509_crt_verify_name( crt, cn, &ee_flags );
|
|
|
|
if( ret != 0 )
|
|
|
|
return( ret );
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
mbedtls_pk_context *pk;
|
|
|
|
mbedtls_pk_type_t pk_type;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2019-02-25 14:50:14 +01:00
|
|
|
ret = mbedtls_x509_crt_pk_acquire( crt, &pk );
|
2019-02-25 19:15:33 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
return( MBEDTLS_ERR_X509_FATAL_ERROR );
|
|
|
|
|
|
|
|
/* Check the type and size of the key */
|
|
|
|
pk_type = mbedtls_pk_get_type( pk );
|
2015-10-23 14:08:48 +02:00
|
|
|
|
2019-02-25 19:15:33 +01:00
|
|
|
if( x509_profile_check_pk_alg( profile, pk_type ) != 0 )
|
|
|
|
ee_flags |= MBEDTLS_X509_BADCERT_BAD_PK;
|
2015-10-23 14:08:48 +02:00
|
|
|
|
2019-02-25 19:15:33 +01:00
|
|
|
if( x509_profile_check_key( profile, pk ) != 0 )
|
|
|
|
ee_flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
|
|
|
|
|
2019-03-05 14:50:56 +01:00
|
|
|
mbedtls_x509_crt_pk_release( crt );
|
2019-02-25 19:15:33 +01:00
|
|
|
}
|
2015-10-23 14:08:48 +02:00
|
|
|
|
2017-07-04 00:33:39 +02:00
|
|
|
/* Check the chain */
|
2017-07-05 17:36:47 +02:00
|
|
|
ret = x509_crt_verify_chain( crt, trust_ca, ca_crl, profile,
|
2017-08-14 17:17:14 +02:00
|
|
|
&ver_chain, rs_ctx );
|
2017-07-17 10:26:19 +02:00
|
|
|
|
2017-07-05 13:28:45 +02:00
|
|
|
if( ret != 0 )
|
|
|
|
goto exit;
|
|
|
|
|
2017-08-23 10:55:41 +02:00
|
|
|
/* Merge end-entity flags */
|
|
|
|
ver_chain.items[0].flags |= ee_flags;
|
|
|
|
|
2017-07-05 17:18:42 +02:00
|
|
|
/* Build final flags, calling callback on the way if any */
|
2017-08-14 17:17:14 +02:00
|
|
|
ret = x509_crt_merge_flags_with_cb( flags, &ver_chain, f_vrfy, p_vrfy );
|
2012-09-28 09:10:55 +02:00
|
|
|
|
2017-06-22 12:19:27 +02:00
|
|
|
exit:
|
2017-08-14 18:04:19 +02:00
|
|
|
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
|
|
|
if( rs_ctx != NULL && ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
|
|
|
|
mbedtls_x509_crt_restart_free( rs_ctx );
|
|
|
|
#endif
|
|
|
|
|
2017-07-06 12:16:25 +02:00
|
|
|
/* prevent misuse of the vrfy callback - VERIFY_FAILED would be ignored by
|
|
|
|
* the SSL module for authmode optional, but non-zero return from the
|
|
|
|
* callback means a fatal error so it shouldn't be ignored */
|
2017-06-26 10:11:49 +02:00
|
|
|
if( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED )
|
|
|
|
ret = MBEDTLS_ERR_X509_FATAL_ERROR;
|
|
|
|
|
2017-06-22 12:19:27 +02:00
|
|
|
if( ret != 0 )
|
|
|
|
{
|
|
|
|
*flags = (uint32_t) -1;
|
|
|
|
return( ret );
|
|
|
|
}
|
|
|
|
|
2012-09-28 09:10:55 +02:00
|
|
|
if( *flags != 0 )
|
2015-04-08 12:49:31 +02:00
|
|
|
return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED );
|
2011-01-13 18:54:59 +01:00
|
|
|
|
2009-01-03 22:22:43 +01:00
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
2013-09-18 11:58:25 +02:00
|
|
|
/*
|
|
|
|
* Initialize a certificate chain
|
|
|
|
*/
|
2015-04-08 12:49:31 +02:00
|
|
|
void mbedtls_x509_crt_init( mbedtls_x509_crt *crt )
|
2013-09-18 11:58:25 +02:00
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
memset( crt, 0, sizeof(mbedtls_x509_crt) );
|
2013-09-18 11:58:25 +02:00
|
|
|
}
|
|
|
|
|
2009-01-03 22:22:43 +01:00
|
|
|
/*
|
|
|
|
* Unallocate all certificate data
|
|
|
|
*/
|
2019-02-15 18:15:53 +01:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
void mbedtls_x509_crt_free( mbedtls_x509_crt *crt )
|
2009-01-03 22:22:43 +01:00
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_x509_crt *cert_cur = crt;
|
|
|
|
mbedtls_x509_crt *cert_prv;
|
2009-01-03 22:22:43 +01:00
|
|
|
|
|
|
|
if( crt == NULL )
|
|
|
|
return;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
2019-02-25 14:50:14 +01:00
|
|
|
x509_crt_cache_free( cert_cur->cache );
|
|
|
|
mbedtls_free( cert_cur->cache );
|
2019-02-28 14:23:38 +01:00
|
|
|
|
|
|
|
#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING)
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_pk_free( &cert_cur->pk );
|
2009-01-03 22:22:43 +01:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
|
|
|
|
mbedtls_free( cert_cur->sig_opts );
|
2014-06-05 15:14:28 +02:00
|
|
|
#endif
|
|
|
|
|
2019-02-26 20:01:00 +01:00
|
|
|
mbedtls_x509_name_free( cert_cur->issuer.next );
|
|
|
|
mbedtls_x509_name_free( cert_cur->subject.next );
|
|
|
|
mbedtls_x509_sequence_free( cert_cur->ext_key_usage.next );
|
|
|
|
mbedtls_x509_sequence_free( cert_cur->subject_alt_names.next );
|
2019-02-28 14:23:38 +01:00
|
|
|
#endif /* !MBEDTLS_X509_ON_DEMAND_PARSING */
|
2012-02-11 19:42:45 +01:00
|
|
|
|
2019-01-31 09:57:44 +01:00
|
|
|
if( cert_cur->raw.p != NULL && cert_cur->own_buffer )
|
2009-01-03 22:22:43 +01:00
|
|
|
{
|
2018-04-17 16:51:09 +02:00
|
|
|
mbedtls_platform_zeroize( cert_cur->raw.p, cert_cur->raw.len );
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_free( cert_cur->raw.p );
|
2009-01-03 22:22:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
cert_cur = cert_cur->next;
|
|
|
|
}
|
|
|
|
while( cert_cur != NULL );
|
|
|
|
|
|
|
|
cert_cur = crt;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
cert_prv = cert_cur;
|
|
|
|
cert_cur = cert_cur->next;
|
|
|
|
|
2018-04-17 16:51:09 +02:00
|
|
|
mbedtls_platform_zeroize( cert_prv, sizeof( mbedtls_x509_crt ) );
|
2009-01-03 22:22:43 +01:00
|
|
|
if( cert_prv != crt )
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_free( cert_prv );
|
2009-01-03 22:22:43 +01:00
|
|
|
}
|
|
|
|
while( cert_cur != NULL );
|
|
|
|
}
|
|
|
|
|
2017-07-11 11:02:20 +02:00
|
|
|
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
|
|
|
|
/*
|
|
|
|
* Initialize a restart context
|
|
|
|
*/
|
|
|
|
void mbedtls_x509_crt_restart_init( mbedtls_x509_crt_restart_ctx *ctx )
|
|
|
|
{
|
2017-08-17 14:33:31 +02:00
|
|
|
mbedtls_pk_restart_init( &ctx->pk );
|
2017-08-14 18:04:19 +02:00
|
|
|
|
|
|
|
ctx->parent = NULL;
|
2019-06-10 12:12:33 +02:00
|
|
|
#if defined(MBEDTLS_HAVE_TIME_DATE)
|
2017-08-14 18:04:19 +02:00
|
|
|
ctx->fallback_parent = NULL;
|
2018-07-02 12:33:14 +02:00
|
|
|
ctx->fallback_signature_is_good = 0;
|
2019-06-10 12:12:33 +02:00
|
|
|
#endif /* MBEDTLS_HAVE_TIME_DATE */
|
2017-08-14 18:04:19 +02:00
|
|
|
|
|
|
|
ctx->parent_is_trusted = -1;
|
|
|
|
|
2017-08-23 12:32:19 +02:00
|
|
|
ctx->in_progress = x509_crt_rs_none;
|
2017-08-14 18:04:19 +02:00
|
|
|
ctx->self_cnt = 0;
|
2017-08-23 10:55:41 +02:00
|
|
|
x509_crt_verify_chain_reset( &ctx->ver_chain );
|
2017-07-11 11:02:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Free the components of a restart context
|
|
|
|
*/
|
|
|
|
void mbedtls_x509_crt_restart_free( mbedtls_x509_crt_restart_ctx *ctx )
|
|
|
|
{
|
|
|
|
if( ctx == NULL )
|
|
|
|
return;
|
|
|
|
|
2017-08-17 14:33:31 +02:00
|
|
|
mbedtls_pk_restart_free( &ctx->pk );
|
2017-08-14 18:04:19 +02:00
|
|
|
mbedtls_x509_crt_restart_init( ctx );
|
2017-07-11 11:02:20 +02:00
|
|
|
}
|
|
|
|
#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|