BA / SerialCom

Fork of OmniWheels by Gustav Atmel

Committer:
gustavatmel
Date:
Tue May 01 15:47:08 2018 +0000
Revision:
1:9c5af431a1f1
sdf

Who changed what in which revision?

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