Greg Steiert / pegasus_dev

Dependents:   blinky_max32630fthr

Committer:
switches
Date:
Fri Nov 11 20:59:50 2016 +0000
Revision:
0:5c4d7b2438d3
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
switches 0:5c4d7b2438d3 1 /*
switches 0:5c4d7b2438d3 2 * X.509 common functions for parsing and verification
switches 0:5c4d7b2438d3 3 *
switches 0:5c4d7b2438d3 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
switches 0:5c4d7b2438d3 5 * SPDX-License-Identifier: Apache-2.0
switches 0:5c4d7b2438d3 6 *
switches 0:5c4d7b2438d3 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
switches 0:5c4d7b2438d3 8 * not use this file except in compliance with the License.
switches 0:5c4d7b2438d3 9 * You may obtain a copy of the License at
switches 0:5c4d7b2438d3 10 *
switches 0:5c4d7b2438d3 11 * http://www.apache.org/licenses/LICENSE-2.0
switches 0:5c4d7b2438d3 12 *
switches 0:5c4d7b2438d3 13 * Unless required by applicable law or agreed to in writing, software
switches 0:5c4d7b2438d3 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
switches 0:5c4d7b2438d3 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
switches 0:5c4d7b2438d3 16 * See the License for the specific language governing permissions and
switches 0:5c4d7b2438d3 17 * limitations under the License.
switches 0:5c4d7b2438d3 18 *
switches 0:5c4d7b2438d3 19 * This file is part of mbed TLS (https://tls.mbed.org)
switches 0:5c4d7b2438d3 20 */
switches 0:5c4d7b2438d3 21 /*
switches 0:5c4d7b2438d3 22 * The ITU-T X.509 standard defines a certificate format for PKI.
switches 0:5c4d7b2438d3 23 *
switches 0:5c4d7b2438d3 24 * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
switches 0:5c4d7b2438d3 25 * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
switches 0:5c4d7b2438d3 26 * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
switches 0:5c4d7b2438d3 27 *
switches 0:5c4d7b2438d3 28 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
switches 0:5c4d7b2438d3 29 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
switches 0:5c4d7b2438d3 30 */
switches 0:5c4d7b2438d3 31
switches 0:5c4d7b2438d3 32 #if !defined(MBEDTLS_CONFIG_FILE)
switches 0:5c4d7b2438d3 33 #include "mbedtls/config.h"
switches 0:5c4d7b2438d3 34 #else
switches 0:5c4d7b2438d3 35 #include MBEDTLS_CONFIG_FILE
switches 0:5c4d7b2438d3 36 #endif
switches 0:5c4d7b2438d3 37
switches 0:5c4d7b2438d3 38 #if defined(MBEDTLS_X509_USE_C)
switches 0:5c4d7b2438d3 39
switches 0:5c4d7b2438d3 40 #include "mbedtls/x509.h"
switches 0:5c4d7b2438d3 41 #include "mbedtls/asn1.h"
switches 0:5c4d7b2438d3 42 #include "mbedtls/oid.h"
switches 0:5c4d7b2438d3 43
switches 0:5c4d7b2438d3 44 #include <stdio.h>
switches 0:5c4d7b2438d3 45 #include <string.h>
switches 0:5c4d7b2438d3 46
switches 0:5c4d7b2438d3 47 #if defined(MBEDTLS_PEM_PARSE_C)
switches 0:5c4d7b2438d3 48 #include "mbedtls/pem.h"
switches 0:5c4d7b2438d3 49 #endif
switches 0:5c4d7b2438d3 50
switches 0:5c4d7b2438d3 51 #if defined(MBEDTLS_PLATFORM_C)
switches 0:5c4d7b2438d3 52 #include "mbedtls/platform.h"
switches 0:5c4d7b2438d3 53 #else
switches 0:5c4d7b2438d3 54 #include <stdio.h>
switches 0:5c4d7b2438d3 55 #include <stdlib.h>
switches 0:5c4d7b2438d3 56 #define mbedtls_free free
switches 0:5c4d7b2438d3 57 #define mbedtls_calloc calloc
switches 0:5c4d7b2438d3 58 #define mbedtls_printf printf
switches 0:5c4d7b2438d3 59 #define mbedtls_snprintf snprintf
switches 0:5c4d7b2438d3 60 #endif
switches 0:5c4d7b2438d3 61
switches 0:5c4d7b2438d3 62
switches 0:5c4d7b2438d3 63 #if defined(MBEDTLS_HAVE_TIME)
switches 0:5c4d7b2438d3 64 #include "mbedtls/platform_time.h"
switches 0:5c4d7b2438d3 65 #endif
switches 0:5c4d7b2438d3 66
switches 0:5c4d7b2438d3 67 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
switches 0:5c4d7b2438d3 68 #include <windows.h>
switches 0:5c4d7b2438d3 69 #else
switches 0:5c4d7b2438d3 70 #include <time.h>
switches 0:5c4d7b2438d3 71 #endif
switches 0:5c4d7b2438d3 72
switches 0:5c4d7b2438d3 73 #if defined(MBEDTLS_FS_IO)
switches 0:5c4d7b2438d3 74 #include <stdio.h>
switches 0:5c4d7b2438d3 75 #if !defined(_WIN32)
switches 0:5c4d7b2438d3 76 #include <sys/types.h>
switches 0:5c4d7b2438d3 77 #include <sys/stat.h>
switches 0:5c4d7b2438d3 78 #include <dirent.h>
switches 0:5c4d7b2438d3 79 #endif
switches 0:5c4d7b2438d3 80 #endif
switches 0:5c4d7b2438d3 81
switches 0:5c4d7b2438d3 82 #define CHECK(code) if( ( ret = code ) != 0 ){ return( ret ); }
switches 0:5c4d7b2438d3 83 #define CHECK_RANGE(min, max, val) if( val < min || val > max ){ return( ret ); }
switches 0:5c4d7b2438d3 84
switches 0:5c4d7b2438d3 85 /*
switches 0:5c4d7b2438d3 86 * CertificateSerialNumber ::= INTEGER
switches 0:5c4d7b2438d3 87 */
switches 0:5c4d7b2438d3 88 int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end,
switches 0:5c4d7b2438d3 89 mbedtls_x509_buf *serial )
switches 0:5c4d7b2438d3 90 {
switches 0:5c4d7b2438d3 91 int ret;
switches 0:5c4d7b2438d3 92
switches 0:5c4d7b2438d3 93 if( ( end - *p ) < 1 )
switches 0:5c4d7b2438d3 94 return( MBEDTLS_ERR_X509_INVALID_SERIAL +
switches 0:5c4d7b2438d3 95 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
switches 0:5c4d7b2438d3 96
switches 0:5c4d7b2438d3 97 if( **p != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_PRIMITIVE | 2 ) &&
switches 0:5c4d7b2438d3 98 **p != MBEDTLS_ASN1_INTEGER )
switches 0:5c4d7b2438d3 99 return( MBEDTLS_ERR_X509_INVALID_SERIAL +
switches 0:5c4d7b2438d3 100 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
switches 0:5c4d7b2438d3 101
switches 0:5c4d7b2438d3 102 serial->tag = *(*p)++;
switches 0:5c4d7b2438d3 103
switches 0:5c4d7b2438d3 104 if( ( ret = mbedtls_asn1_get_len( p, end, &serial->len ) ) != 0 )
switches 0:5c4d7b2438d3 105 return( MBEDTLS_ERR_X509_INVALID_SERIAL + ret );
switches 0:5c4d7b2438d3 106
switches 0:5c4d7b2438d3 107 serial->p = *p;
switches 0:5c4d7b2438d3 108 *p += serial->len;
switches 0:5c4d7b2438d3 109
switches 0:5c4d7b2438d3 110 return( 0 );
switches 0:5c4d7b2438d3 111 }
switches 0:5c4d7b2438d3 112
switches 0:5c4d7b2438d3 113 /* Get an algorithm identifier without parameters (eg for signatures)
switches 0:5c4d7b2438d3 114 *
switches 0:5c4d7b2438d3 115 * AlgorithmIdentifier ::= SEQUENCE {
switches 0:5c4d7b2438d3 116 * algorithm OBJECT IDENTIFIER,
switches 0:5c4d7b2438d3 117 * parameters ANY DEFINED BY algorithm OPTIONAL }
switches 0:5c4d7b2438d3 118 */
switches 0:5c4d7b2438d3 119 int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end,
switches 0:5c4d7b2438d3 120 mbedtls_x509_buf *alg )
switches 0:5c4d7b2438d3 121 {
switches 0:5c4d7b2438d3 122 int ret;
switches 0:5c4d7b2438d3 123
switches 0:5c4d7b2438d3 124 if( ( ret = mbedtls_asn1_get_alg_null( p, end, alg ) ) != 0 )
switches 0:5c4d7b2438d3 125 return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
switches 0:5c4d7b2438d3 126
switches 0:5c4d7b2438d3 127 return( 0 );
switches 0:5c4d7b2438d3 128 }
switches 0:5c4d7b2438d3 129
switches 0:5c4d7b2438d3 130 /*
switches 0:5c4d7b2438d3 131 * Parse an algorithm identifier with (optional) paramaters
switches 0:5c4d7b2438d3 132 */
switches 0:5c4d7b2438d3 133 int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end,
switches 0:5c4d7b2438d3 134 mbedtls_x509_buf *alg, mbedtls_x509_buf *params )
switches 0:5c4d7b2438d3 135 {
switches 0:5c4d7b2438d3 136 int ret;
switches 0:5c4d7b2438d3 137
switches 0:5c4d7b2438d3 138 if( ( ret = mbedtls_asn1_get_alg( p, end, alg, params ) ) != 0 )
switches 0:5c4d7b2438d3 139 return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
switches 0:5c4d7b2438d3 140
switches 0:5c4d7b2438d3 141 return( 0 );
switches 0:5c4d7b2438d3 142 }
switches 0:5c4d7b2438d3 143
switches 0:5c4d7b2438d3 144 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
switches 0:5c4d7b2438d3 145 /*
switches 0:5c4d7b2438d3 146 * HashAlgorithm ::= AlgorithmIdentifier
switches 0:5c4d7b2438d3 147 *
switches 0:5c4d7b2438d3 148 * AlgorithmIdentifier ::= SEQUENCE {
switches 0:5c4d7b2438d3 149 * algorithm OBJECT IDENTIFIER,
switches 0:5c4d7b2438d3 150 * parameters ANY DEFINED BY algorithm OPTIONAL }
switches 0:5c4d7b2438d3 151 *
switches 0:5c4d7b2438d3 152 * For HashAlgorithm, parameters MUST be NULL or absent.
switches 0:5c4d7b2438d3 153 */
switches 0:5c4d7b2438d3 154 static int x509_get_hash_alg( const mbedtls_x509_buf *alg, mbedtls_md_type_t *md_alg )
switches 0:5c4d7b2438d3 155 {
switches 0:5c4d7b2438d3 156 int ret;
switches 0:5c4d7b2438d3 157 unsigned char *p;
switches 0:5c4d7b2438d3 158 const unsigned char *end;
switches 0:5c4d7b2438d3 159 mbedtls_x509_buf md_oid;
switches 0:5c4d7b2438d3 160 size_t len;
switches 0:5c4d7b2438d3 161
switches 0:5c4d7b2438d3 162 /* Make sure we got a SEQUENCE and setup bounds */
switches 0:5c4d7b2438d3 163 if( alg->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
switches 0:5c4d7b2438d3 164 return( MBEDTLS_ERR_X509_INVALID_ALG +
switches 0:5c4d7b2438d3 165 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
switches 0:5c4d7b2438d3 166
switches 0:5c4d7b2438d3 167 p = (unsigned char *) alg->p;
switches 0:5c4d7b2438d3 168 end = p + alg->len;
switches 0:5c4d7b2438d3 169
switches 0:5c4d7b2438d3 170 if( p >= end )
switches 0:5c4d7b2438d3 171 return( MBEDTLS_ERR_X509_INVALID_ALG +
switches 0:5c4d7b2438d3 172 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
switches 0:5c4d7b2438d3 173
switches 0:5c4d7b2438d3 174 /* Parse md_oid */
switches 0:5c4d7b2438d3 175 md_oid.tag = *p;
switches 0:5c4d7b2438d3 176
switches 0:5c4d7b2438d3 177 if( ( ret = mbedtls_asn1_get_tag( &p, end, &md_oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
switches 0:5c4d7b2438d3 178 return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
switches 0:5c4d7b2438d3 179
switches 0:5c4d7b2438d3 180 md_oid.p = p;
switches 0:5c4d7b2438d3 181 p += md_oid.len;
switches 0:5c4d7b2438d3 182
switches 0:5c4d7b2438d3 183 /* Get md_alg from md_oid */
switches 0:5c4d7b2438d3 184 if( ( ret = mbedtls_oid_get_md_alg( &md_oid, md_alg ) ) != 0 )
switches 0:5c4d7b2438d3 185 return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
switches 0:5c4d7b2438d3 186
switches 0:5c4d7b2438d3 187 /* Make sure params is absent of NULL */
switches 0:5c4d7b2438d3 188 if( p == end )
switches 0:5c4d7b2438d3 189 return( 0 );
switches 0:5c4d7b2438d3 190
switches 0:5c4d7b2438d3 191 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_NULL ) ) != 0 || len != 0 )
switches 0:5c4d7b2438d3 192 return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
switches 0:5c4d7b2438d3 193
switches 0:5c4d7b2438d3 194 if( p != end )
switches 0:5c4d7b2438d3 195 return( MBEDTLS_ERR_X509_INVALID_ALG +
switches 0:5c4d7b2438d3 196 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
switches 0:5c4d7b2438d3 197
switches 0:5c4d7b2438d3 198 return( 0 );
switches 0:5c4d7b2438d3 199 }
switches 0:5c4d7b2438d3 200
switches 0:5c4d7b2438d3 201 /*
switches 0:5c4d7b2438d3 202 * RSASSA-PSS-params ::= SEQUENCE {
switches 0:5c4d7b2438d3 203 * hashAlgorithm [0] HashAlgorithm DEFAULT sha1Identifier,
switches 0:5c4d7b2438d3 204 * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier,
switches 0:5c4d7b2438d3 205 * saltLength [2] INTEGER DEFAULT 20,
switches 0:5c4d7b2438d3 206 * trailerField [3] INTEGER DEFAULT 1 }
switches 0:5c4d7b2438d3 207 * -- Note that the tags in this Sequence are explicit.
switches 0:5c4d7b2438d3 208 *
switches 0:5c4d7b2438d3 209 * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value
switches 0:5c4d7b2438d3 210 * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other
switches 0:5c4d7b2438d3 211 * option. Enfore this at parsing time.
switches 0:5c4d7b2438d3 212 */
switches 0:5c4d7b2438d3 213 int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
switches 0:5c4d7b2438d3 214 mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md,
switches 0:5c4d7b2438d3 215 int *salt_len )
switches 0:5c4d7b2438d3 216 {
switches 0:5c4d7b2438d3 217 int ret;
switches 0:5c4d7b2438d3 218 unsigned char *p;
switches 0:5c4d7b2438d3 219 const unsigned char *end, *end2;
switches 0:5c4d7b2438d3 220 size_t len;
switches 0:5c4d7b2438d3 221 mbedtls_x509_buf alg_id, alg_params;
switches 0:5c4d7b2438d3 222
switches 0:5c4d7b2438d3 223 /* First set everything to defaults */
switches 0:5c4d7b2438d3 224 *md_alg = MBEDTLS_MD_SHA1;
switches 0:5c4d7b2438d3 225 *mgf_md = MBEDTLS_MD_SHA1;
switches 0:5c4d7b2438d3 226 *salt_len = 20;
switches 0:5c4d7b2438d3 227
switches 0:5c4d7b2438d3 228 /* Make sure params is a SEQUENCE and setup bounds */
switches 0:5c4d7b2438d3 229 if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
switches 0:5c4d7b2438d3 230 return( MBEDTLS_ERR_X509_INVALID_ALG +
switches 0:5c4d7b2438d3 231 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
switches 0:5c4d7b2438d3 232
switches 0:5c4d7b2438d3 233 p = (unsigned char *) params->p;
switches 0:5c4d7b2438d3 234 end = p + params->len;
switches 0:5c4d7b2438d3 235
switches 0:5c4d7b2438d3 236 if( p == end )
switches 0:5c4d7b2438d3 237 return( 0 );
switches 0:5c4d7b2438d3 238
switches 0:5c4d7b2438d3 239 /*
switches 0:5c4d7b2438d3 240 * HashAlgorithm
switches 0:5c4d7b2438d3 241 */
switches 0:5c4d7b2438d3 242 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
switches 0:5c4d7b2438d3 243 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 )
switches 0:5c4d7b2438d3 244 {
switches 0:5c4d7b2438d3 245 end2 = p + len;
switches 0:5c4d7b2438d3 246
switches 0:5c4d7b2438d3 247 /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */
switches 0:5c4d7b2438d3 248 if( ( ret = mbedtls_x509_get_alg_null( &p, end2, &alg_id ) ) != 0 )
switches 0:5c4d7b2438d3 249 return( ret );
switches 0:5c4d7b2438d3 250
switches 0:5c4d7b2438d3 251 if( ( ret = mbedtls_oid_get_md_alg( &alg_id, md_alg ) ) != 0 )
switches 0:5c4d7b2438d3 252 return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
switches 0:5c4d7b2438d3 253
switches 0:5c4d7b2438d3 254 if( p != end2 )
switches 0:5c4d7b2438d3 255 return( MBEDTLS_ERR_X509_INVALID_ALG +
switches 0:5c4d7b2438d3 256 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
switches 0:5c4d7b2438d3 257 }
switches 0:5c4d7b2438d3 258 else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
switches 0:5c4d7b2438d3 259 return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
switches 0:5c4d7b2438d3 260
switches 0:5c4d7b2438d3 261 if( p == end )
switches 0:5c4d7b2438d3 262 return( 0 );
switches 0:5c4d7b2438d3 263
switches 0:5c4d7b2438d3 264 /*
switches 0:5c4d7b2438d3 265 * MaskGenAlgorithm
switches 0:5c4d7b2438d3 266 */
switches 0:5c4d7b2438d3 267 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
switches 0:5c4d7b2438d3 268 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 )
switches 0:5c4d7b2438d3 269 {
switches 0:5c4d7b2438d3 270 end2 = p + len;
switches 0:5c4d7b2438d3 271
switches 0:5c4d7b2438d3 272 /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */
switches 0:5c4d7b2438d3 273 if( ( ret = mbedtls_x509_get_alg( &p, end2, &alg_id, &alg_params ) ) != 0 )
switches 0:5c4d7b2438d3 274 return( ret );
switches 0:5c4d7b2438d3 275
switches 0:5c4d7b2438d3 276 /* Only MFG1 is recognised for now */
switches 0:5c4d7b2438d3 277 if( MBEDTLS_OID_CMP( MBEDTLS_OID_MGF1, &alg_id ) != 0 )
switches 0:5c4d7b2438d3 278 return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE +
switches 0:5c4d7b2438d3 279 MBEDTLS_ERR_OID_NOT_FOUND );
switches 0:5c4d7b2438d3 280
switches 0:5c4d7b2438d3 281 /* Parse HashAlgorithm */
switches 0:5c4d7b2438d3 282 if( ( ret = x509_get_hash_alg( &alg_params, mgf_md ) ) != 0 )
switches 0:5c4d7b2438d3 283 return( ret );
switches 0:5c4d7b2438d3 284
switches 0:5c4d7b2438d3 285 if( p != end2 )
switches 0:5c4d7b2438d3 286 return( MBEDTLS_ERR_X509_INVALID_ALG +
switches 0:5c4d7b2438d3 287 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
switches 0:5c4d7b2438d3 288 }
switches 0:5c4d7b2438d3 289 else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
switches 0:5c4d7b2438d3 290 return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
switches 0:5c4d7b2438d3 291
switches 0:5c4d7b2438d3 292 if( p == end )
switches 0:5c4d7b2438d3 293 return( 0 );
switches 0:5c4d7b2438d3 294
switches 0:5c4d7b2438d3 295 /*
switches 0:5c4d7b2438d3 296 * salt_len
switches 0:5c4d7b2438d3 297 */
switches 0:5c4d7b2438d3 298 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
switches 0:5c4d7b2438d3 299 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 2 ) ) == 0 )
switches 0:5c4d7b2438d3 300 {
switches 0:5c4d7b2438d3 301 end2 = p + len;
switches 0:5c4d7b2438d3 302
switches 0:5c4d7b2438d3 303 if( ( ret = mbedtls_asn1_get_int( &p, end2, salt_len ) ) != 0 )
switches 0:5c4d7b2438d3 304 return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
switches 0:5c4d7b2438d3 305
switches 0:5c4d7b2438d3 306 if( p != end2 )
switches 0:5c4d7b2438d3 307 return( MBEDTLS_ERR_X509_INVALID_ALG +
switches 0:5c4d7b2438d3 308 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
switches 0:5c4d7b2438d3 309 }
switches 0:5c4d7b2438d3 310 else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
switches 0:5c4d7b2438d3 311 return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
switches 0:5c4d7b2438d3 312
switches 0:5c4d7b2438d3 313 if( p == end )
switches 0:5c4d7b2438d3 314 return( 0 );
switches 0:5c4d7b2438d3 315
switches 0:5c4d7b2438d3 316 /*
switches 0:5c4d7b2438d3 317 * trailer_field (if present, must be 1)
switches 0:5c4d7b2438d3 318 */
switches 0:5c4d7b2438d3 319 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
switches 0:5c4d7b2438d3 320 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 3 ) ) == 0 )
switches 0:5c4d7b2438d3 321 {
switches 0:5c4d7b2438d3 322 int trailer_field;
switches 0:5c4d7b2438d3 323
switches 0:5c4d7b2438d3 324 end2 = p + len;
switches 0:5c4d7b2438d3 325
switches 0:5c4d7b2438d3 326 if( ( ret = mbedtls_asn1_get_int( &p, end2, &trailer_field ) ) != 0 )
switches 0:5c4d7b2438d3 327 return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
switches 0:5c4d7b2438d3 328
switches 0:5c4d7b2438d3 329 if( p != end2 )
switches 0:5c4d7b2438d3 330 return( MBEDTLS_ERR_X509_INVALID_ALG +
switches 0:5c4d7b2438d3 331 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
switches 0:5c4d7b2438d3 332
switches 0:5c4d7b2438d3 333 if( trailer_field != 1 )
switches 0:5c4d7b2438d3 334 return( MBEDTLS_ERR_X509_INVALID_ALG );
switches 0:5c4d7b2438d3 335 }
switches 0:5c4d7b2438d3 336 else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
switches 0:5c4d7b2438d3 337 return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
switches 0:5c4d7b2438d3 338
switches 0:5c4d7b2438d3 339 if( p != end )
switches 0:5c4d7b2438d3 340 return( MBEDTLS_ERR_X509_INVALID_ALG +
switches 0:5c4d7b2438d3 341 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
switches 0:5c4d7b2438d3 342
switches 0:5c4d7b2438d3 343 return( 0 );
switches 0:5c4d7b2438d3 344 }
switches 0:5c4d7b2438d3 345 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
switches 0:5c4d7b2438d3 346
switches 0:5c4d7b2438d3 347 /*
switches 0:5c4d7b2438d3 348 * AttributeTypeAndValue ::= SEQUENCE {
switches 0:5c4d7b2438d3 349 * type AttributeType,
switches 0:5c4d7b2438d3 350 * value AttributeValue }
switches 0:5c4d7b2438d3 351 *
switches 0:5c4d7b2438d3 352 * AttributeType ::= OBJECT IDENTIFIER
switches 0:5c4d7b2438d3 353 *
switches 0:5c4d7b2438d3 354 * AttributeValue ::= ANY DEFINED BY AttributeType
switches 0:5c4d7b2438d3 355 */
switches 0:5c4d7b2438d3 356 static int x509_get_attr_type_value( unsigned char **p,
switches 0:5c4d7b2438d3 357 const unsigned char *end,
switches 0:5c4d7b2438d3 358 mbedtls_x509_name *cur )
switches 0:5c4d7b2438d3 359 {
switches 0:5c4d7b2438d3 360 int ret;
switches 0:5c4d7b2438d3 361 size_t len;
switches 0:5c4d7b2438d3 362 mbedtls_x509_buf *oid;
switches 0:5c4d7b2438d3 363 mbedtls_x509_buf *val;
switches 0:5c4d7b2438d3 364
switches 0:5c4d7b2438d3 365 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
switches 0:5c4d7b2438d3 366 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
switches 0:5c4d7b2438d3 367 return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
switches 0:5c4d7b2438d3 368
switches 0:5c4d7b2438d3 369 if( ( end - *p ) < 1 )
switches 0:5c4d7b2438d3 370 return( MBEDTLS_ERR_X509_INVALID_NAME +
switches 0:5c4d7b2438d3 371 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
switches 0:5c4d7b2438d3 372
switches 0:5c4d7b2438d3 373 oid = &cur->oid;
switches 0:5c4d7b2438d3 374 oid->tag = **p;
switches 0:5c4d7b2438d3 375
switches 0:5c4d7b2438d3 376 if( ( ret = mbedtls_asn1_get_tag( p, end, &oid->len, MBEDTLS_ASN1_OID ) ) != 0 )
switches 0:5c4d7b2438d3 377 return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
switches 0:5c4d7b2438d3 378
switches 0:5c4d7b2438d3 379 oid->p = *p;
switches 0:5c4d7b2438d3 380 *p += oid->len;
switches 0:5c4d7b2438d3 381
switches 0:5c4d7b2438d3 382 if( ( end - *p ) < 1 )
switches 0:5c4d7b2438d3 383 return( MBEDTLS_ERR_X509_INVALID_NAME +
switches 0:5c4d7b2438d3 384 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
switches 0:5c4d7b2438d3 385
switches 0:5c4d7b2438d3 386 if( **p != MBEDTLS_ASN1_BMP_STRING && **p != MBEDTLS_ASN1_UTF8_STRING &&
switches 0:5c4d7b2438d3 387 **p != MBEDTLS_ASN1_T61_STRING && **p != MBEDTLS_ASN1_PRINTABLE_STRING &&
switches 0:5c4d7b2438d3 388 **p != MBEDTLS_ASN1_IA5_STRING && **p != MBEDTLS_ASN1_UNIVERSAL_STRING &&
switches 0:5c4d7b2438d3 389 **p != MBEDTLS_ASN1_BIT_STRING )
switches 0:5c4d7b2438d3 390 return( MBEDTLS_ERR_X509_INVALID_NAME +
switches 0:5c4d7b2438d3 391 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
switches 0:5c4d7b2438d3 392
switches 0:5c4d7b2438d3 393 val = &cur->val;
switches 0:5c4d7b2438d3 394 val->tag = *(*p)++;
switches 0:5c4d7b2438d3 395
switches 0:5c4d7b2438d3 396 if( ( ret = mbedtls_asn1_get_len( p, end, &val->len ) ) != 0 )
switches 0:5c4d7b2438d3 397 return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
switches 0:5c4d7b2438d3 398
switches 0:5c4d7b2438d3 399 val->p = *p;
switches 0:5c4d7b2438d3 400 *p += val->len;
switches 0:5c4d7b2438d3 401
switches 0:5c4d7b2438d3 402 cur->next = NULL;
switches 0:5c4d7b2438d3 403
switches 0:5c4d7b2438d3 404 return( 0 );
switches 0:5c4d7b2438d3 405 }
switches 0:5c4d7b2438d3 406
switches 0:5c4d7b2438d3 407 /*
switches 0:5c4d7b2438d3 408 * Name ::= CHOICE { -- only one possibility for now --
switches 0:5c4d7b2438d3 409 * rdnSequence RDNSequence }
switches 0:5c4d7b2438d3 410 *
switches 0:5c4d7b2438d3 411 * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
switches 0:5c4d7b2438d3 412 *
switches 0:5c4d7b2438d3 413 * RelativeDistinguishedName ::=
switches 0:5c4d7b2438d3 414 * SET OF AttributeTypeAndValue
switches 0:5c4d7b2438d3 415 *
switches 0:5c4d7b2438d3 416 * AttributeTypeAndValue ::= SEQUENCE {
switches 0:5c4d7b2438d3 417 * type AttributeType,
switches 0:5c4d7b2438d3 418 * value AttributeValue }
switches 0:5c4d7b2438d3 419 *
switches 0:5c4d7b2438d3 420 * AttributeType ::= OBJECT IDENTIFIER
switches 0:5c4d7b2438d3 421 *
switches 0:5c4d7b2438d3 422 * AttributeValue ::= ANY DEFINED BY AttributeType
switches 0:5c4d7b2438d3 423 *
switches 0:5c4d7b2438d3 424 * The data structure is optimized for the common case where each RDN has only
switches 0:5c4d7b2438d3 425 * one element, which is represented as a list of AttributeTypeAndValue.
switches 0:5c4d7b2438d3 426 * For the general case we still use a flat list, but we mark elements of the
switches 0:5c4d7b2438d3 427 * same set so that they are "merged" together in the functions that consume
switches 0:5c4d7b2438d3 428 * this list, eg mbedtls_x509_dn_gets().
switches 0:5c4d7b2438d3 429 */
switches 0:5c4d7b2438d3 430 int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end,
switches 0:5c4d7b2438d3 431 mbedtls_x509_name *cur )
switches 0:5c4d7b2438d3 432 {
switches 0:5c4d7b2438d3 433 int ret;
switches 0:5c4d7b2438d3 434 size_t set_len;
switches 0:5c4d7b2438d3 435 const unsigned char *end_set;
switches 0:5c4d7b2438d3 436
switches 0:5c4d7b2438d3 437 /* don't use recursion, we'd risk stack overflow if not optimized */
switches 0:5c4d7b2438d3 438 while( 1 )
switches 0:5c4d7b2438d3 439 {
switches 0:5c4d7b2438d3 440 /*
switches 0:5c4d7b2438d3 441 * parse SET
switches 0:5c4d7b2438d3 442 */
switches 0:5c4d7b2438d3 443 if( ( ret = mbedtls_asn1_get_tag( p, end, &set_len,
switches 0:5c4d7b2438d3 444 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) ) != 0 )
switches 0:5c4d7b2438d3 445 return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
switches 0:5c4d7b2438d3 446
switches 0:5c4d7b2438d3 447 end_set = *p + set_len;
switches 0:5c4d7b2438d3 448
switches 0:5c4d7b2438d3 449 while( 1 )
switches 0:5c4d7b2438d3 450 {
switches 0:5c4d7b2438d3 451 if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 )
switches 0:5c4d7b2438d3 452 return( ret );
switches 0:5c4d7b2438d3 453
switches 0:5c4d7b2438d3 454 if( *p == end_set )
switches 0:5c4d7b2438d3 455 break;
switches 0:5c4d7b2438d3 456
switches 0:5c4d7b2438d3 457 /* Mark this item as being no the only one in a set */
switches 0:5c4d7b2438d3 458 cur->next_merged = 1;
switches 0:5c4d7b2438d3 459
switches 0:5c4d7b2438d3 460 cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) );
switches 0:5c4d7b2438d3 461
switches 0:5c4d7b2438d3 462 if( cur->next == NULL )
switches 0:5c4d7b2438d3 463 return( MBEDTLS_ERR_X509_ALLOC_FAILED );
switches 0:5c4d7b2438d3 464
switches 0:5c4d7b2438d3 465 cur = cur->next;
switches 0:5c4d7b2438d3 466 }
switches 0:5c4d7b2438d3 467
switches 0:5c4d7b2438d3 468 /*
switches 0:5c4d7b2438d3 469 * continue until end of SEQUENCE is reached
switches 0:5c4d7b2438d3 470 */
switches 0:5c4d7b2438d3 471 if( *p == end )
switches 0:5c4d7b2438d3 472 return( 0 );
switches 0:5c4d7b2438d3 473
switches 0:5c4d7b2438d3 474 cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) );
switches 0:5c4d7b2438d3 475
switches 0:5c4d7b2438d3 476 if( cur->next == NULL )
switches 0:5c4d7b2438d3 477 return( MBEDTLS_ERR_X509_ALLOC_FAILED );
switches 0:5c4d7b2438d3 478
switches 0:5c4d7b2438d3 479 cur = cur->next;
switches 0:5c4d7b2438d3 480 }
switches 0:5c4d7b2438d3 481 }
switches 0:5c4d7b2438d3 482
switches 0:5c4d7b2438d3 483 static int x509_parse_int(unsigned char **p, unsigned n, int *res){
switches 0:5c4d7b2438d3 484 *res = 0;
switches 0:5c4d7b2438d3 485 for( ; n > 0; --n ){
switches 0:5c4d7b2438d3 486 if( ( **p < '0') || ( **p > '9' ) ) return MBEDTLS_ERR_X509_INVALID_DATE;
switches 0:5c4d7b2438d3 487 *res *= 10;
switches 0:5c4d7b2438d3 488 *res += (*(*p)++ - '0');
switches 0:5c4d7b2438d3 489 }
switches 0:5c4d7b2438d3 490 return 0;
switches 0:5c4d7b2438d3 491 }
switches 0:5c4d7b2438d3 492
switches 0:5c4d7b2438d3 493 static int x509_date_is_valid(const mbedtls_x509_time *time)
switches 0:5c4d7b2438d3 494 {
switches 0:5c4d7b2438d3 495 int ret = MBEDTLS_ERR_X509_INVALID_DATE;
switches 0:5c4d7b2438d3 496
switches 0:5c4d7b2438d3 497 CHECK_RANGE( 0, 9999, time->year );
switches 0:5c4d7b2438d3 498 CHECK_RANGE( 0, 23, time->hour );
switches 0:5c4d7b2438d3 499 CHECK_RANGE( 0, 59, time->min );
switches 0:5c4d7b2438d3 500 CHECK_RANGE( 0, 59, time->sec );
switches 0:5c4d7b2438d3 501
switches 0:5c4d7b2438d3 502 switch( time->mon )
switches 0:5c4d7b2438d3 503 {
switches 0:5c4d7b2438d3 504 case 1: case 3: case 5: case 7: case 8: case 10: case 12:
switches 0:5c4d7b2438d3 505 CHECK_RANGE( 1, 31, time->day );
switches 0:5c4d7b2438d3 506 break;
switches 0:5c4d7b2438d3 507 case 4: case 6: case 9: case 11:
switches 0:5c4d7b2438d3 508 CHECK_RANGE( 1, 30, time->day );
switches 0:5c4d7b2438d3 509 break;
switches 0:5c4d7b2438d3 510 case 2:
switches 0:5c4d7b2438d3 511 CHECK_RANGE( 1, 28 + (time->year % 4 == 0), time->day );
switches 0:5c4d7b2438d3 512 break;
switches 0:5c4d7b2438d3 513 default:
switches 0:5c4d7b2438d3 514 return( ret );
switches 0:5c4d7b2438d3 515 }
switches 0:5c4d7b2438d3 516
switches 0:5c4d7b2438d3 517 return( 0 );
switches 0:5c4d7b2438d3 518 }
switches 0:5c4d7b2438d3 519
switches 0:5c4d7b2438d3 520 /*
switches 0:5c4d7b2438d3 521 * Time ::= CHOICE {
switches 0:5c4d7b2438d3 522 * utcTime UTCTime,
switches 0:5c4d7b2438d3 523 * generalTime GeneralizedTime }
switches 0:5c4d7b2438d3 524 */
switches 0:5c4d7b2438d3 525 int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end,
switches 0:5c4d7b2438d3 526 mbedtls_x509_time *time )
switches 0:5c4d7b2438d3 527 {
switches 0:5c4d7b2438d3 528 int ret;
switches 0:5c4d7b2438d3 529 size_t len;
switches 0:5c4d7b2438d3 530 unsigned char tag;
switches 0:5c4d7b2438d3 531
switches 0:5c4d7b2438d3 532 if( ( end - *p ) < 1 )
switches 0:5c4d7b2438d3 533 return( MBEDTLS_ERR_X509_INVALID_DATE +
switches 0:5c4d7b2438d3 534 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
switches 0:5c4d7b2438d3 535
switches 0:5c4d7b2438d3 536 tag = **p;
switches 0:5c4d7b2438d3 537
switches 0:5c4d7b2438d3 538 if( tag == MBEDTLS_ASN1_UTC_TIME )
switches 0:5c4d7b2438d3 539 {
switches 0:5c4d7b2438d3 540 (*p)++;
switches 0:5c4d7b2438d3 541 ret = mbedtls_asn1_get_len( p, end, &len );
switches 0:5c4d7b2438d3 542
switches 0:5c4d7b2438d3 543 if( ret != 0 )
switches 0:5c4d7b2438d3 544 return( MBEDTLS_ERR_X509_INVALID_DATE + ret );
switches 0:5c4d7b2438d3 545
switches 0:5c4d7b2438d3 546 CHECK( x509_parse_int( p, 2, &time->year ) );
switches 0:5c4d7b2438d3 547 CHECK( x509_parse_int( p, 2, &time->mon ) );
switches 0:5c4d7b2438d3 548 CHECK( x509_parse_int( p, 2, &time->day ) );
switches 0:5c4d7b2438d3 549 CHECK( x509_parse_int( p, 2, &time->hour ) );
switches 0:5c4d7b2438d3 550 CHECK( x509_parse_int( p, 2, &time->min ) );
switches 0:5c4d7b2438d3 551 if( len > 10 )
switches 0:5c4d7b2438d3 552 CHECK( x509_parse_int( p, 2, &time->sec ) );
switches 0:5c4d7b2438d3 553 if( len > 12 && *(*p)++ != 'Z' )
switches 0:5c4d7b2438d3 554 return( MBEDTLS_ERR_X509_INVALID_DATE );
switches 0:5c4d7b2438d3 555
switches 0:5c4d7b2438d3 556 time->year += 100 * ( time->year < 50 );
switches 0:5c4d7b2438d3 557 time->year += 1900;
switches 0:5c4d7b2438d3 558
switches 0:5c4d7b2438d3 559 CHECK( x509_date_is_valid( time ) );
switches 0:5c4d7b2438d3 560
switches 0:5c4d7b2438d3 561 return( 0 );
switches 0:5c4d7b2438d3 562 }
switches 0:5c4d7b2438d3 563 else if( tag == MBEDTLS_ASN1_GENERALIZED_TIME )
switches 0:5c4d7b2438d3 564 {
switches 0:5c4d7b2438d3 565 (*p)++;
switches 0:5c4d7b2438d3 566 ret = mbedtls_asn1_get_len( p, end, &len );
switches 0:5c4d7b2438d3 567
switches 0:5c4d7b2438d3 568 if( ret != 0 )
switches 0:5c4d7b2438d3 569 return( MBEDTLS_ERR_X509_INVALID_DATE + ret );
switches 0:5c4d7b2438d3 570
switches 0:5c4d7b2438d3 571 CHECK( x509_parse_int( p, 4, &time->year ) );
switches 0:5c4d7b2438d3 572 CHECK( x509_parse_int( p, 2, &time->mon ) );
switches 0:5c4d7b2438d3 573 CHECK( x509_parse_int( p, 2, &time->day ) );
switches 0:5c4d7b2438d3 574 CHECK( x509_parse_int( p, 2, &time->hour ) );
switches 0:5c4d7b2438d3 575 CHECK( x509_parse_int( p, 2, &time->min ) );
switches 0:5c4d7b2438d3 576 if( len > 12 )
switches 0:5c4d7b2438d3 577 CHECK( x509_parse_int( p, 2, &time->sec ) );
switches 0:5c4d7b2438d3 578 if( len > 14 && *(*p)++ != 'Z' )
switches 0:5c4d7b2438d3 579 return( MBEDTLS_ERR_X509_INVALID_DATE );
switches 0:5c4d7b2438d3 580
switches 0:5c4d7b2438d3 581 CHECK( x509_date_is_valid( time ) );
switches 0:5c4d7b2438d3 582
switches 0:5c4d7b2438d3 583 return( 0 );
switches 0:5c4d7b2438d3 584 }
switches 0:5c4d7b2438d3 585 else
switches 0:5c4d7b2438d3 586 return( MBEDTLS_ERR_X509_INVALID_DATE +
switches 0:5c4d7b2438d3 587 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
switches 0:5c4d7b2438d3 588 }
switches 0:5c4d7b2438d3 589
switches 0:5c4d7b2438d3 590 int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig )
switches 0:5c4d7b2438d3 591 {
switches 0:5c4d7b2438d3 592 int ret;
switches 0:5c4d7b2438d3 593 size_t len;
switches 0:5c4d7b2438d3 594 int tag_type;
switches 0:5c4d7b2438d3 595
switches 0:5c4d7b2438d3 596 if( ( end - *p ) < 1 )
switches 0:5c4d7b2438d3 597 return( MBEDTLS_ERR_X509_INVALID_SIGNATURE +
switches 0:5c4d7b2438d3 598 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
switches 0:5c4d7b2438d3 599
switches 0:5c4d7b2438d3 600 tag_type = **p;
switches 0:5c4d7b2438d3 601
switches 0:5c4d7b2438d3 602 if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 )
switches 0:5c4d7b2438d3 603 return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + ret );
switches 0:5c4d7b2438d3 604
switches 0:5c4d7b2438d3 605 sig->tag = tag_type;
switches 0:5c4d7b2438d3 606 sig->len = len;
switches 0:5c4d7b2438d3 607 sig->p = *p;
switches 0:5c4d7b2438d3 608
switches 0:5c4d7b2438d3 609 *p += len;
switches 0:5c4d7b2438d3 610
switches 0:5c4d7b2438d3 611 return( 0 );
switches 0:5c4d7b2438d3 612 }
switches 0:5c4d7b2438d3 613
switches 0:5c4d7b2438d3 614 /*
switches 0:5c4d7b2438d3 615 * Get signature algorithm from alg OID and optional parameters
switches 0:5c4d7b2438d3 616 */
switches 0:5c4d7b2438d3 617 int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params,
switches 0:5c4d7b2438d3 618 mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg,
switches 0:5c4d7b2438d3 619 void **sig_opts )
switches 0:5c4d7b2438d3 620 {
switches 0:5c4d7b2438d3 621 int ret;
switches 0:5c4d7b2438d3 622
switches 0:5c4d7b2438d3 623 if( *sig_opts != NULL )
switches 0:5c4d7b2438d3 624 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
switches 0:5c4d7b2438d3 625
switches 0:5c4d7b2438d3 626 if( ( ret = mbedtls_oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 )
switches 0:5c4d7b2438d3 627 return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + ret );
switches 0:5c4d7b2438d3 628
switches 0:5c4d7b2438d3 629 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
switches 0:5c4d7b2438d3 630 if( *pk_alg == MBEDTLS_PK_RSASSA_PSS )
switches 0:5c4d7b2438d3 631 {
switches 0:5c4d7b2438d3 632 mbedtls_pk_rsassa_pss_options *pss_opts;
switches 0:5c4d7b2438d3 633
switches 0:5c4d7b2438d3 634 pss_opts = mbedtls_calloc( 1, sizeof( mbedtls_pk_rsassa_pss_options ) );
switches 0:5c4d7b2438d3 635 if( pss_opts == NULL )
switches 0:5c4d7b2438d3 636 return( MBEDTLS_ERR_X509_ALLOC_FAILED );
switches 0:5c4d7b2438d3 637
switches 0:5c4d7b2438d3 638 ret = mbedtls_x509_get_rsassa_pss_params( sig_params,
switches 0:5c4d7b2438d3 639 md_alg,
switches 0:5c4d7b2438d3 640 &pss_opts->mgf1_hash_id,
switches 0:5c4d7b2438d3 641 &pss_opts->expected_salt_len );
switches 0:5c4d7b2438d3 642 if( ret != 0 )
switches 0:5c4d7b2438d3 643 {
switches 0:5c4d7b2438d3 644 mbedtls_free( pss_opts );
switches 0:5c4d7b2438d3 645 return( ret );
switches 0:5c4d7b2438d3 646 }
switches 0:5c4d7b2438d3 647
switches 0:5c4d7b2438d3 648 *sig_opts = (void *) pss_opts;
switches 0:5c4d7b2438d3 649 }
switches 0:5c4d7b2438d3 650 else
switches 0:5c4d7b2438d3 651 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
switches 0:5c4d7b2438d3 652 {
switches 0:5c4d7b2438d3 653 /* Make sure parameters are absent or NULL */
switches 0:5c4d7b2438d3 654 if( ( sig_params->tag != MBEDTLS_ASN1_NULL && sig_params->tag != 0 ) ||
switches 0:5c4d7b2438d3 655 sig_params->len != 0 )
switches 0:5c4d7b2438d3 656 return( MBEDTLS_ERR_X509_INVALID_ALG );
switches 0:5c4d7b2438d3 657 }
switches 0:5c4d7b2438d3 658
switches 0:5c4d7b2438d3 659 return( 0 );
switches 0:5c4d7b2438d3 660 }
switches 0:5c4d7b2438d3 661
switches 0:5c4d7b2438d3 662 /*
switches 0:5c4d7b2438d3 663 * X.509 Extensions (No parsing of extensions, pointer should
switches 0:5c4d7b2438d3 664 * be either manually updated or extensions should be parsed!
switches 0:5c4d7b2438d3 665 */
switches 0:5c4d7b2438d3 666 int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end,
switches 0:5c4d7b2438d3 667 mbedtls_x509_buf *ext, int tag )
switches 0:5c4d7b2438d3 668 {
switches 0:5c4d7b2438d3 669 int ret;
switches 0:5c4d7b2438d3 670 size_t len;
switches 0:5c4d7b2438d3 671
switches 0:5c4d7b2438d3 672 if( *p == end )
switches 0:5c4d7b2438d3 673 return( 0 );
switches 0:5c4d7b2438d3 674
switches 0:5c4d7b2438d3 675 ext->tag = **p;
switches 0:5c4d7b2438d3 676
switches 0:5c4d7b2438d3 677 if( ( ret = mbedtls_asn1_get_tag( p, end, &ext->len,
switches 0:5c4d7b2438d3 678 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag ) ) != 0 )
switches 0:5c4d7b2438d3 679 return( ret );
switches 0:5c4d7b2438d3 680
switches 0:5c4d7b2438d3 681 ext->p = *p;
switches 0:5c4d7b2438d3 682 end = *p + ext->len;
switches 0:5c4d7b2438d3 683
switches 0:5c4d7b2438d3 684 /*
switches 0:5c4d7b2438d3 685 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
switches 0:5c4d7b2438d3 686 *
switches 0:5c4d7b2438d3 687 * Extension ::= SEQUENCE {
switches 0:5c4d7b2438d3 688 * extnID OBJECT IDENTIFIER,
switches 0:5c4d7b2438d3 689 * critical BOOLEAN DEFAULT FALSE,
switches 0:5c4d7b2438d3 690 * extnValue OCTET STRING }
switches 0:5c4d7b2438d3 691 */
switches 0:5c4d7b2438d3 692 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
switches 0:5c4d7b2438d3 693 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
switches 0:5c4d7b2438d3 694 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
switches 0:5c4d7b2438d3 695
switches 0:5c4d7b2438d3 696 if( end != *p + len )
switches 0:5c4d7b2438d3 697 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
switches 0:5c4d7b2438d3 698 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
switches 0:5c4d7b2438d3 699
switches 0:5c4d7b2438d3 700 return( 0 );
switches 0:5c4d7b2438d3 701 }
switches 0:5c4d7b2438d3 702
switches 0:5c4d7b2438d3 703 /*
switches 0:5c4d7b2438d3 704 * Store the name in printable form into buf; no more
switches 0:5c4d7b2438d3 705 * than size characters will be written
switches 0:5c4d7b2438d3 706 */
switches 0:5c4d7b2438d3 707 int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn )
switches 0:5c4d7b2438d3 708 {
switches 0:5c4d7b2438d3 709 int ret;
switches 0:5c4d7b2438d3 710 size_t i, n;
switches 0:5c4d7b2438d3 711 unsigned char c, merge = 0;
switches 0:5c4d7b2438d3 712 const mbedtls_x509_name *name;
switches 0:5c4d7b2438d3 713 const char *short_name = NULL;
switches 0:5c4d7b2438d3 714 char s[MBEDTLS_X509_MAX_DN_NAME_SIZE], *p;
switches 0:5c4d7b2438d3 715
switches 0:5c4d7b2438d3 716 memset( s, 0, sizeof( s ) );
switches 0:5c4d7b2438d3 717
switches 0:5c4d7b2438d3 718 name = dn;
switches 0:5c4d7b2438d3 719 p = buf;
switches 0:5c4d7b2438d3 720 n = size;
switches 0:5c4d7b2438d3 721
switches 0:5c4d7b2438d3 722 while( name != NULL )
switches 0:5c4d7b2438d3 723 {
switches 0:5c4d7b2438d3 724 if( !name->oid.p )
switches 0:5c4d7b2438d3 725 {
switches 0:5c4d7b2438d3 726 name = name->next;
switches 0:5c4d7b2438d3 727 continue;
switches 0:5c4d7b2438d3 728 }
switches 0:5c4d7b2438d3 729
switches 0:5c4d7b2438d3 730 if( name != dn )
switches 0:5c4d7b2438d3 731 {
switches 0:5c4d7b2438d3 732 ret = mbedtls_snprintf( p, n, merge ? " + " : ", " );
switches 0:5c4d7b2438d3 733 MBEDTLS_X509_SAFE_SNPRINTF;
switches 0:5c4d7b2438d3 734 }
switches 0:5c4d7b2438d3 735
switches 0:5c4d7b2438d3 736 ret = mbedtls_oid_get_attr_short_name( &name->oid, &short_name );
switches 0:5c4d7b2438d3 737
switches 0:5c4d7b2438d3 738 if( ret == 0 )
switches 0:5c4d7b2438d3 739 ret = mbedtls_snprintf( p, n, "%s=", short_name );
switches 0:5c4d7b2438d3 740 else
switches 0:5c4d7b2438d3 741 ret = mbedtls_snprintf( p, n, "\?\?=" );
switches 0:5c4d7b2438d3 742 MBEDTLS_X509_SAFE_SNPRINTF;
switches 0:5c4d7b2438d3 743
switches 0:5c4d7b2438d3 744 for( i = 0; i < name->val.len; i++ )
switches 0:5c4d7b2438d3 745 {
switches 0:5c4d7b2438d3 746 if( i >= sizeof( s ) - 1 )
switches 0:5c4d7b2438d3 747 break;
switches 0:5c4d7b2438d3 748
switches 0:5c4d7b2438d3 749 c = name->val.p[i];
switches 0:5c4d7b2438d3 750 if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
switches 0:5c4d7b2438d3 751 s[i] = '?';
switches 0:5c4d7b2438d3 752 else s[i] = c;
switches 0:5c4d7b2438d3 753 }
switches 0:5c4d7b2438d3 754 s[i] = '\0';
switches 0:5c4d7b2438d3 755 ret = mbedtls_snprintf( p, n, "%s", s );
switches 0:5c4d7b2438d3 756 MBEDTLS_X509_SAFE_SNPRINTF;
switches 0:5c4d7b2438d3 757
switches 0:5c4d7b2438d3 758 merge = name->next_merged;
switches 0:5c4d7b2438d3 759 name = name->next;
switches 0:5c4d7b2438d3 760 }
switches 0:5c4d7b2438d3 761
switches 0:5c4d7b2438d3 762 return( (int) ( size - n ) );
switches 0:5c4d7b2438d3 763 }
switches 0:5c4d7b2438d3 764
switches 0:5c4d7b2438d3 765 /*
switches 0:5c4d7b2438d3 766 * Store the serial in printable form into buf; no more
switches 0:5c4d7b2438d3 767 * than size characters will be written
switches 0:5c4d7b2438d3 768 */
switches 0:5c4d7b2438d3 769 int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial )
switches 0:5c4d7b2438d3 770 {
switches 0:5c4d7b2438d3 771 int ret;
switches 0:5c4d7b2438d3 772 size_t i, n, nr;
switches 0:5c4d7b2438d3 773 char *p;
switches 0:5c4d7b2438d3 774
switches 0:5c4d7b2438d3 775 p = buf;
switches 0:5c4d7b2438d3 776 n = size;
switches 0:5c4d7b2438d3 777
switches 0:5c4d7b2438d3 778 nr = ( serial->len <= 32 )
switches 0:5c4d7b2438d3 779 ? serial->len : 28;
switches 0:5c4d7b2438d3 780
switches 0:5c4d7b2438d3 781 for( i = 0; i < nr; i++ )
switches 0:5c4d7b2438d3 782 {
switches 0:5c4d7b2438d3 783 if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
switches 0:5c4d7b2438d3 784 continue;
switches 0:5c4d7b2438d3 785
switches 0:5c4d7b2438d3 786 ret = mbedtls_snprintf( p, n, "%02X%s",
switches 0:5c4d7b2438d3 787 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
switches 0:5c4d7b2438d3 788 MBEDTLS_X509_SAFE_SNPRINTF;
switches 0:5c4d7b2438d3 789 }
switches 0:5c4d7b2438d3 790
switches 0:5c4d7b2438d3 791 if( nr != serial->len )
switches 0:5c4d7b2438d3 792 {
switches 0:5c4d7b2438d3 793 ret = mbedtls_snprintf( p, n, "...." );
switches 0:5c4d7b2438d3 794 MBEDTLS_X509_SAFE_SNPRINTF;
switches 0:5c4d7b2438d3 795 }
switches 0:5c4d7b2438d3 796
switches 0:5c4d7b2438d3 797 return( (int) ( size - n ) );
switches 0:5c4d7b2438d3 798 }
switches 0:5c4d7b2438d3 799
switches 0:5c4d7b2438d3 800 /*
switches 0:5c4d7b2438d3 801 * Helper for writing signature algorithms
switches 0:5c4d7b2438d3 802 */
switches 0:5c4d7b2438d3 803 int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid,
switches 0:5c4d7b2438d3 804 mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
switches 0:5c4d7b2438d3 805 const void *sig_opts )
switches 0:5c4d7b2438d3 806 {
switches 0:5c4d7b2438d3 807 int ret;
switches 0:5c4d7b2438d3 808 char *p = buf;
switches 0:5c4d7b2438d3 809 size_t n = size;
switches 0:5c4d7b2438d3 810 const char *desc = NULL;
switches 0:5c4d7b2438d3 811
switches 0:5c4d7b2438d3 812 ret = mbedtls_oid_get_sig_alg_desc( sig_oid, &desc );
switches 0:5c4d7b2438d3 813 if( ret != 0 )
switches 0:5c4d7b2438d3 814 ret = mbedtls_snprintf( p, n, "???" );
switches 0:5c4d7b2438d3 815 else
switches 0:5c4d7b2438d3 816 ret = mbedtls_snprintf( p, n, "%s", desc );
switches 0:5c4d7b2438d3 817 MBEDTLS_X509_SAFE_SNPRINTF;
switches 0:5c4d7b2438d3 818
switches 0:5c4d7b2438d3 819 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
switches 0:5c4d7b2438d3 820 if( pk_alg == MBEDTLS_PK_RSASSA_PSS )
switches 0:5c4d7b2438d3 821 {
switches 0:5c4d7b2438d3 822 const mbedtls_pk_rsassa_pss_options *pss_opts;
switches 0:5c4d7b2438d3 823 const mbedtls_md_info_t *md_info, *mgf_md_info;
switches 0:5c4d7b2438d3 824
switches 0:5c4d7b2438d3 825 pss_opts = (const mbedtls_pk_rsassa_pss_options *) sig_opts;
switches 0:5c4d7b2438d3 826
switches 0:5c4d7b2438d3 827 md_info = mbedtls_md_info_from_type( md_alg );
switches 0:5c4d7b2438d3 828 mgf_md_info = mbedtls_md_info_from_type( pss_opts->mgf1_hash_id );
switches 0:5c4d7b2438d3 829
switches 0:5c4d7b2438d3 830 ret = mbedtls_snprintf( p, n, " (%s, MGF1-%s, 0x%02X)",
switches 0:5c4d7b2438d3 831 md_info ? mbedtls_md_get_name( md_info ) : "???",
switches 0:5c4d7b2438d3 832 mgf_md_info ? mbedtls_md_get_name( mgf_md_info ) : "???",
switches 0:5c4d7b2438d3 833 pss_opts->expected_salt_len );
switches 0:5c4d7b2438d3 834 MBEDTLS_X509_SAFE_SNPRINTF;
switches 0:5c4d7b2438d3 835 }
switches 0:5c4d7b2438d3 836 #else
switches 0:5c4d7b2438d3 837 ((void) pk_alg);
switches 0:5c4d7b2438d3 838 ((void) md_alg);
switches 0:5c4d7b2438d3 839 ((void) sig_opts);
switches 0:5c4d7b2438d3 840 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
switches 0:5c4d7b2438d3 841
switches 0:5c4d7b2438d3 842 return( (int)( size - n ) );
switches 0:5c4d7b2438d3 843 }
switches 0:5c4d7b2438d3 844
switches 0:5c4d7b2438d3 845 /*
switches 0:5c4d7b2438d3 846 * Helper for writing "RSA key size", "EC key size", etc
switches 0:5c4d7b2438d3 847 */
switches 0:5c4d7b2438d3 848 int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name )
switches 0:5c4d7b2438d3 849 {
switches 0:5c4d7b2438d3 850 char *p = buf;
switches 0:5c4d7b2438d3 851 size_t n = buf_size;
switches 0:5c4d7b2438d3 852 int ret;
switches 0:5c4d7b2438d3 853
switches 0:5c4d7b2438d3 854 ret = mbedtls_snprintf( p, n, "%s key size", name );
switches 0:5c4d7b2438d3 855 MBEDTLS_X509_SAFE_SNPRINTF;
switches 0:5c4d7b2438d3 856
switches 0:5c4d7b2438d3 857 return( 0 );
switches 0:5c4d7b2438d3 858 }
switches 0:5c4d7b2438d3 859
switches 0:5c4d7b2438d3 860 #if defined(MBEDTLS_HAVE_TIME_DATE)
switches 0:5c4d7b2438d3 861 /*
switches 0:5c4d7b2438d3 862 * Set the time structure to the current time.
switches 0:5c4d7b2438d3 863 * Return 0 on success, non-zero on failure.
switches 0:5c4d7b2438d3 864 */
switches 0:5c4d7b2438d3 865 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
switches 0:5c4d7b2438d3 866 static int x509_get_current_time( mbedtls_x509_time *now )
switches 0:5c4d7b2438d3 867 {
switches 0:5c4d7b2438d3 868 SYSTEMTIME st;
switches 0:5c4d7b2438d3 869
switches 0:5c4d7b2438d3 870 GetSystemTime( &st );
switches 0:5c4d7b2438d3 871
switches 0:5c4d7b2438d3 872 now->year = st.wYear;
switches 0:5c4d7b2438d3 873 now->mon = st.wMonth;
switches 0:5c4d7b2438d3 874 now->day = st.wDay;
switches 0:5c4d7b2438d3 875 now->hour = st.wHour;
switches 0:5c4d7b2438d3 876 now->min = st.wMinute;
switches 0:5c4d7b2438d3 877 now->sec = st.wSecond;
switches 0:5c4d7b2438d3 878
switches 0:5c4d7b2438d3 879 return( 0 );
switches 0:5c4d7b2438d3 880 }
switches 0:5c4d7b2438d3 881 #else
switches 0:5c4d7b2438d3 882 static int x509_get_current_time( mbedtls_x509_time *now )
switches 0:5c4d7b2438d3 883 {
switches 0:5c4d7b2438d3 884 struct tm *lt;
switches 0:5c4d7b2438d3 885 mbedtls_time_t tt;
switches 0:5c4d7b2438d3 886 int ret = 0;
switches 0:5c4d7b2438d3 887
switches 0:5c4d7b2438d3 888 #if defined(MBEDTLS_THREADING_C)
switches 0:5c4d7b2438d3 889 if( mbedtls_mutex_lock( &mbedtls_threading_gmtime_mutex ) != 0 )
switches 0:5c4d7b2438d3 890 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
switches 0:5c4d7b2438d3 891 #endif
switches 0:5c4d7b2438d3 892
switches 0:5c4d7b2438d3 893 tt = mbedtls_time( NULL );
switches 0:5c4d7b2438d3 894 lt = gmtime( &tt );
switches 0:5c4d7b2438d3 895
switches 0:5c4d7b2438d3 896 if( lt == NULL )
switches 0:5c4d7b2438d3 897 ret = -1;
switches 0:5c4d7b2438d3 898 else
switches 0:5c4d7b2438d3 899 {
switches 0:5c4d7b2438d3 900 now->year = lt->tm_year + 1900;
switches 0:5c4d7b2438d3 901 now->mon = lt->tm_mon + 1;
switches 0:5c4d7b2438d3 902 now->day = lt->tm_mday;
switches 0:5c4d7b2438d3 903 now->hour = lt->tm_hour;
switches 0:5c4d7b2438d3 904 now->min = lt->tm_min;
switches 0:5c4d7b2438d3 905 now->sec = lt->tm_sec;
switches 0:5c4d7b2438d3 906 }
switches 0:5c4d7b2438d3 907
switches 0:5c4d7b2438d3 908 #if defined(MBEDTLS_THREADING_C)
switches 0:5c4d7b2438d3 909 if( mbedtls_mutex_unlock( &mbedtls_threading_gmtime_mutex ) != 0 )
switches 0:5c4d7b2438d3 910 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
switches 0:5c4d7b2438d3 911 #endif
switches 0:5c4d7b2438d3 912
switches 0:5c4d7b2438d3 913 return( ret );
switches 0:5c4d7b2438d3 914 }
switches 0:5c4d7b2438d3 915 #endif /* _WIN32 && !EFIX64 && !EFI32 */
switches 0:5c4d7b2438d3 916
switches 0:5c4d7b2438d3 917 /*
switches 0:5c4d7b2438d3 918 * Return 0 if before <= after, 1 otherwise
switches 0:5c4d7b2438d3 919 */
switches 0:5c4d7b2438d3 920 static int x509_check_time( const mbedtls_x509_time *before, const mbedtls_x509_time *after )
switches 0:5c4d7b2438d3 921 {
switches 0:5c4d7b2438d3 922 if( before->year > after->year )
switches 0:5c4d7b2438d3 923 return( 1 );
switches 0:5c4d7b2438d3 924
switches 0:5c4d7b2438d3 925 if( before->year == after->year &&
switches 0:5c4d7b2438d3 926 before->mon > after->mon )
switches 0:5c4d7b2438d3 927 return( 1 );
switches 0:5c4d7b2438d3 928
switches 0:5c4d7b2438d3 929 if( before->year == after->year &&
switches 0:5c4d7b2438d3 930 before->mon == after->mon &&
switches 0:5c4d7b2438d3 931 before->day > after->day )
switches 0:5c4d7b2438d3 932 return( 1 );
switches 0:5c4d7b2438d3 933
switches 0:5c4d7b2438d3 934 if( before->year == after->year &&
switches 0:5c4d7b2438d3 935 before->mon == after->mon &&
switches 0:5c4d7b2438d3 936 before->day == after->day &&
switches 0:5c4d7b2438d3 937 before->hour > after->hour )
switches 0:5c4d7b2438d3 938 return( 1 );
switches 0:5c4d7b2438d3 939
switches 0:5c4d7b2438d3 940 if( before->year == after->year &&
switches 0:5c4d7b2438d3 941 before->mon == after->mon &&
switches 0:5c4d7b2438d3 942 before->day == after->day &&
switches 0:5c4d7b2438d3 943 before->hour == after->hour &&
switches 0:5c4d7b2438d3 944 before->min > after->min )
switches 0:5c4d7b2438d3 945 return( 1 );
switches 0:5c4d7b2438d3 946
switches 0:5c4d7b2438d3 947 if( before->year == after->year &&
switches 0:5c4d7b2438d3 948 before->mon == after->mon &&
switches 0:5c4d7b2438d3 949 before->day == after->day &&
switches 0:5c4d7b2438d3 950 before->hour == after->hour &&
switches 0:5c4d7b2438d3 951 before->min == after->min &&
switches 0:5c4d7b2438d3 952 before->sec > after->sec )
switches 0:5c4d7b2438d3 953 return( 1 );
switches 0:5c4d7b2438d3 954
switches 0:5c4d7b2438d3 955 return( 0 );
switches 0:5c4d7b2438d3 956 }
switches 0:5c4d7b2438d3 957
switches 0:5c4d7b2438d3 958 int mbedtls_x509_time_is_past( const mbedtls_x509_time *to )
switches 0:5c4d7b2438d3 959 {
switches 0:5c4d7b2438d3 960 mbedtls_x509_time now;
switches 0:5c4d7b2438d3 961
switches 0:5c4d7b2438d3 962 if( x509_get_current_time( &now ) != 0 )
switches 0:5c4d7b2438d3 963 return( 1 );
switches 0:5c4d7b2438d3 964
switches 0:5c4d7b2438d3 965 return( x509_check_time( &now, to ) );
switches 0:5c4d7b2438d3 966 }
switches 0:5c4d7b2438d3 967
switches 0:5c4d7b2438d3 968 int mbedtls_x509_time_is_future( const mbedtls_x509_time *from )
switches 0:5c4d7b2438d3 969 {
switches 0:5c4d7b2438d3 970 mbedtls_x509_time now;
switches 0:5c4d7b2438d3 971
switches 0:5c4d7b2438d3 972 if( x509_get_current_time( &now ) != 0 )
switches 0:5c4d7b2438d3 973 return( 1 );
switches 0:5c4d7b2438d3 974
switches 0:5c4d7b2438d3 975 return( x509_check_time( from, &now ) );
switches 0:5c4d7b2438d3 976 }
switches 0:5c4d7b2438d3 977
switches 0:5c4d7b2438d3 978 #else /* MBEDTLS_HAVE_TIME_DATE */
switches 0:5c4d7b2438d3 979
switches 0:5c4d7b2438d3 980 int mbedtls_x509_time_is_past( const mbedtls_x509_time *to )
switches 0:5c4d7b2438d3 981 {
switches 0:5c4d7b2438d3 982 ((void) to);
switches 0:5c4d7b2438d3 983 return( 0 );
switches 0:5c4d7b2438d3 984 }
switches 0:5c4d7b2438d3 985
switches 0:5c4d7b2438d3 986 int mbedtls_x509_time_is_future( const mbedtls_x509_time *from )
switches 0:5c4d7b2438d3 987 {
switches 0:5c4d7b2438d3 988 ((void) from);
switches 0:5c4d7b2438d3 989 return( 0 );
switches 0:5c4d7b2438d3 990 }
switches 0:5c4d7b2438d3 991 #endif /* MBEDTLS_HAVE_TIME_DATE */
switches 0:5c4d7b2438d3 992
switches 0:5c4d7b2438d3 993 #if defined(MBEDTLS_SELF_TEST)
switches 0:5c4d7b2438d3 994
switches 0:5c4d7b2438d3 995 #include "mbedtls/x509_crt.h"
switches 0:5c4d7b2438d3 996 #include "mbedtls/certs.h"
switches 0:5c4d7b2438d3 997
switches 0:5c4d7b2438d3 998 /*
switches 0:5c4d7b2438d3 999 * Checkup routine
switches 0:5c4d7b2438d3 1000 */
switches 0:5c4d7b2438d3 1001 int mbedtls_x509_self_test( int verbose )
switches 0:5c4d7b2438d3 1002 {
switches 0:5c4d7b2438d3 1003 #if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_SHA1_C)
switches 0:5c4d7b2438d3 1004 int ret;
switches 0:5c4d7b2438d3 1005 uint32_t flags;
switches 0:5c4d7b2438d3 1006 mbedtls_x509_crt cacert;
switches 0:5c4d7b2438d3 1007 mbedtls_x509_crt clicert;
switches 0:5c4d7b2438d3 1008
switches 0:5c4d7b2438d3 1009 if( verbose != 0 )
switches 0:5c4d7b2438d3 1010 mbedtls_printf( " X.509 certificate load: " );
switches 0:5c4d7b2438d3 1011
switches 0:5c4d7b2438d3 1012 mbedtls_x509_crt_init( &clicert );
switches 0:5c4d7b2438d3 1013
switches 0:5c4d7b2438d3 1014 ret = mbedtls_x509_crt_parse( &clicert, (const unsigned char *) mbedtls_test_cli_crt,
switches 0:5c4d7b2438d3 1015 mbedtls_test_cli_crt_len );
switches 0:5c4d7b2438d3 1016 if( ret != 0 )
switches 0:5c4d7b2438d3 1017 {
switches 0:5c4d7b2438d3 1018 if( verbose != 0 )
switches 0:5c4d7b2438d3 1019 mbedtls_printf( "failed\n" );
switches 0:5c4d7b2438d3 1020
switches 0:5c4d7b2438d3 1021 return( ret );
switches 0:5c4d7b2438d3 1022 }
switches 0:5c4d7b2438d3 1023
switches 0:5c4d7b2438d3 1024 mbedtls_x509_crt_init( &cacert );
switches 0:5c4d7b2438d3 1025
switches 0:5c4d7b2438d3 1026 ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_ca_crt,
switches 0:5c4d7b2438d3 1027 mbedtls_test_ca_crt_len );
switches 0:5c4d7b2438d3 1028 if( ret != 0 )
switches 0:5c4d7b2438d3 1029 {
switches 0:5c4d7b2438d3 1030 if( verbose != 0 )
switches 0:5c4d7b2438d3 1031 mbedtls_printf( "failed\n" );
switches 0:5c4d7b2438d3 1032
switches 0:5c4d7b2438d3 1033 return( ret );
switches 0:5c4d7b2438d3 1034 }
switches 0:5c4d7b2438d3 1035
switches 0:5c4d7b2438d3 1036 if( verbose != 0 )
switches 0:5c4d7b2438d3 1037 mbedtls_printf( "passed\n X.509 signature verify: ");
switches 0:5c4d7b2438d3 1038
switches 0:5c4d7b2438d3 1039 ret = mbedtls_x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL );
switches 0:5c4d7b2438d3 1040 if( ret != 0 )
switches 0:5c4d7b2438d3 1041 {
switches 0:5c4d7b2438d3 1042 if( verbose != 0 )
switches 0:5c4d7b2438d3 1043 mbedtls_printf( "failed\n" );
switches 0:5c4d7b2438d3 1044
switches 0:5c4d7b2438d3 1045 return( ret );
switches 0:5c4d7b2438d3 1046 }
switches 0:5c4d7b2438d3 1047
switches 0:5c4d7b2438d3 1048 if( verbose != 0 )
switches 0:5c4d7b2438d3 1049 mbedtls_printf( "passed\n\n");
switches 0:5c4d7b2438d3 1050
switches 0:5c4d7b2438d3 1051 mbedtls_x509_crt_free( &cacert );
switches 0:5c4d7b2438d3 1052 mbedtls_x509_crt_free( &clicert );
switches 0:5c4d7b2438d3 1053
switches 0:5c4d7b2438d3 1054 return( 0 );
switches 0:5c4d7b2438d3 1055 #else
switches 0:5c4d7b2438d3 1056 ((void) verbose);
switches 0:5c4d7b2438d3 1057 return( 0 );
switches 0:5c4d7b2438d3 1058 #endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA1_C */
switches 0:5c4d7b2438d3 1059 }
switches 0:5c4d7b2438d3 1060
switches 0:5c4d7b2438d3 1061 #endif /* MBEDTLS_SELF_TEST */
switches 0:5c4d7b2438d3 1062
switches 0:5c4d7b2438d3 1063 #endif /* MBEDTLS_X509_USE_C */