BA / Mbed OS BaBoRo_test2
Committer:
borlanic
Date:
Tue Apr 24 11:45:18 2018 +0000
Revision:
0:02dd72d1d465
BaBoRo_test2 - backup 1

Who changed what in which revision?

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