mbedtls ported to mbed-classic

Fork of mbedtls by Christopher Haster

Committer:
Brian Daniels
Date:
Thu Apr 07 11:11:18 2016 +0100
Revision:
4:bef26f687287
Parent:
1:24750b9ad5ef
Adding ported selftest test case

Who changed what in which revision?

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