Preliminary main mbed library for nexpaq development

Committer:
nexpaq
Date:
Fri Nov 04 20:54:50 2016 +0000
Revision:
1:d96dbedaebdb
Parent:
0:6c56fb4bc5f0
Removed extra directories for other platforms

Who changed what in which revision?

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