BBR 1 Ebene

Committer:
borlanic
Date:
Mon May 14 11:29:06 2018 +0000
Revision:
0:fbdae7e6d805
BBR

Who changed what in which revision?

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