RTC auf true

Committer:
kevman
Date:
Wed Mar 13 11:03:24 2019 +0000
Revision:
2:7aab896b1a3b
Parent:
0:38ceb79fef03
2019-03-13

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kevman 0:38ceb79fef03 1 /*
kevman 0:38ceb79fef03 2 * X.509 Certidicate Revocation List (CRL) parsing
kevman 0:38ceb79fef03 3 *
kevman 0:38ceb79fef03 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
kevman 0:38ceb79fef03 5 * SPDX-License-Identifier: Apache-2.0
kevman 0:38ceb79fef03 6 *
kevman 0:38ceb79fef03 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
kevman 0:38ceb79fef03 8 * not use this file except in compliance with the License.
kevman 0:38ceb79fef03 9 * You may obtain a copy of the License at
kevman 0:38ceb79fef03 10 *
kevman 0:38ceb79fef03 11 * http://www.apache.org/licenses/LICENSE-2.0
kevman 0:38ceb79fef03 12 *
kevman 0:38ceb79fef03 13 * Unless required by applicable law or agreed to in writing, software
kevman 0:38ceb79fef03 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
kevman 0:38ceb79fef03 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kevman 0:38ceb79fef03 16 * See the License for the specific language governing permissions and
kevman 0:38ceb79fef03 17 * limitations under the License.
kevman 0:38ceb79fef03 18 *
kevman 0:38ceb79fef03 19 * This file is part of mbed TLS (https://tls.mbed.org)
kevman 0:38ceb79fef03 20 */
kevman 0:38ceb79fef03 21 /*
kevman 0:38ceb79fef03 22 * The ITU-T X.509 standard defines a certificate format for PKI.
kevman 0:38ceb79fef03 23 *
kevman 0:38ceb79fef03 24 * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
kevman 0:38ceb79fef03 25 * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
kevman 0:38ceb79fef03 26 * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
kevman 0:38ceb79fef03 27 *
kevman 0:38ceb79fef03 28 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
kevman 0:38ceb79fef03 29 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
kevman 0:38ceb79fef03 30 */
kevman 0:38ceb79fef03 31
kevman 0:38ceb79fef03 32 #if !defined(MBEDTLS_CONFIG_FILE)
kevman 0:38ceb79fef03 33 #include "mbedtls/config.h"
kevman 0:38ceb79fef03 34 #else
kevman 0:38ceb79fef03 35 #include MBEDTLS_CONFIG_FILE
kevman 0:38ceb79fef03 36 #endif
kevman 0:38ceb79fef03 37
kevman 0:38ceb79fef03 38 #if defined(MBEDTLS_X509_CRL_PARSE_C)
kevman 0:38ceb79fef03 39
kevman 0:38ceb79fef03 40 #include "mbedtls/x509_crl.h"
kevman 0:38ceb79fef03 41 #include "mbedtls/oid.h"
kevman 0:38ceb79fef03 42 #include "mbedtls/platform_util.h"
kevman 0:38ceb79fef03 43
kevman 0:38ceb79fef03 44 #include <string.h>
kevman 0:38ceb79fef03 45
kevman 0:38ceb79fef03 46 #if defined(MBEDTLS_PEM_PARSE_C)
kevman 0:38ceb79fef03 47 #include "mbedtls/pem.h"
kevman 0:38ceb79fef03 48 #endif
kevman 0:38ceb79fef03 49
kevman 0:38ceb79fef03 50 #if defined(MBEDTLS_PLATFORM_C)
kevman 0:38ceb79fef03 51 #include "mbedtls/platform.h"
kevman 0:38ceb79fef03 52 #else
kevman 0:38ceb79fef03 53 #include <stdlib.h>
kevman 0:38ceb79fef03 54 #include <stdio.h>
kevman 0:38ceb79fef03 55 #define mbedtls_free free
kevman 0:38ceb79fef03 56 #define mbedtls_calloc calloc
kevman 0:38ceb79fef03 57 #define mbedtls_snprintf snprintf
kevman 0:38ceb79fef03 58 #endif
kevman 0:38ceb79fef03 59
kevman 0:38ceb79fef03 60 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
kevman 0:38ceb79fef03 61 #include <windows.h>
kevman 0:38ceb79fef03 62 #else
kevman 0:38ceb79fef03 63 #include <time.h>
kevman 0:38ceb79fef03 64 #endif
kevman 0:38ceb79fef03 65
kevman 0:38ceb79fef03 66 #if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32)
kevman 0:38ceb79fef03 67 #include <stdio.h>
kevman 0:38ceb79fef03 68 #endif
kevman 0:38ceb79fef03 69
kevman 0:38ceb79fef03 70 /*
kevman 0:38ceb79fef03 71 * Version ::= INTEGER { v1(0), v2(1) }
kevman 0:38ceb79fef03 72 */
kevman 0:38ceb79fef03 73 static int x509_crl_get_version( unsigned char **p,
kevman 0:38ceb79fef03 74 const unsigned char *end,
kevman 0:38ceb79fef03 75 int *ver )
kevman 0:38ceb79fef03 76 {
kevman 0:38ceb79fef03 77 int ret;
kevman 0:38ceb79fef03 78
kevman 0:38ceb79fef03 79 if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
kevman 0:38ceb79fef03 80 {
kevman 0:38ceb79fef03 81 if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
kevman 0:38ceb79fef03 82 {
kevman 0:38ceb79fef03 83 *ver = 0;
kevman 0:38ceb79fef03 84 return( 0 );
kevman 0:38ceb79fef03 85 }
kevman 0:38ceb79fef03 86
kevman 0:38ceb79fef03 87 return( MBEDTLS_ERR_X509_INVALID_VERSION + ret );
kevman 0:38ceb79fef03 88 }
kevman 0:38ceb79fef03 89
kevman 0:38ceb79fef03 90 return( 0 );
kevman 0:38ceb79fef03 91 }
kevman 0:38ceb79fef03 92
kevman 0:38ceb79fef03 93 /*
kevman 0:38ceb79fef03 94 * X.509 CRL v2 extensions
kevman 0:38ceb79fef03 95 *
kevman 0:38ceb79fef03 96 * We currently don't parse any extension's content, but we do check that the
kevman 0:38ceb79fef03 97 * list of extensions is well-formed and abort on critical extensions (that
kevman 0:38ceb79fef03 98 * are unsupported as we don't support any extension so far)
kevman 0:38ceb79fef03 99 */
kevman 0:38ceb79fef03 100 static int x509_get_crl_ext( unsigned char **p,
kevman 0:38ceb79fef03 101 const unsigned char *end,
kevman 0:38ceb79fef03 102 mbedtls_x509_buf *ext )
kevman 0:38ceb79fef03 103 {
kevman 0:38ceb79fef03 104 int ret;
kevman 0:38ceb79fef03 105
kevman 0:38ceb79fef03 106 /*
kevman 0:38ceb79fef03 107 * crlExtensions [0] EXPLICIT Extensions OPTIONAL
kevman 0:38ceb79fef03 108 * -- if present, version MUST be v2
kevman 0:38ceb79fef03 109 */
kevman 0:38ceb79fef03 110 if( ( ret = mbedtls_x509_get_ext( p, end, ext, 0 ) ) != 0 )
kevman 0:38ceb79fef03 111 {
kevman 0:38ceb79fef03 112 if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
kevman 0:38ceb79fef03 113 return( 0 );
kevman 0:38ceb79fef03 114
kevman 0:38ceb79fef03 115 return( ret );
kevman 0:38ceb79fef03 116 }
kevman 0:38ceb79fef03 117
kevman 0:38ceb79fef03 118 while( *p < end )
kevman 0:38ceb79fef03 119 {
kevman 0:38ceb79fef03 120 /*
kevman 0:38ceb79fef03 121 * Extension ::= SEQUENCE {
kevman 0:38ceb79fef03 122 * extnID OBJECT IDENTIFIER,
kevman 0:38ceb79fef03 123 * critical BOOLEAN DEFAULT FALSE,
kevman 0:38ceb79fef03 124 * extnValue OCTET STRING }
kevman 0:38ceb79fef03 125 */
kevman 0:38ceb79fef03 126 int is_critical = 0;
kevman 0:38ceb79fef03 127 const unsigned char *end_ext_data;
kevman 0:38ceb79fef03 128 size_t len;
kevman 0:38ceb79fef03 129
kevman 0:38ceb79fef03 130 /* Get enclosing sequence tag */
kevman 0:38ceb79fef03 131 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
kevman 0:38ceb79fef03 132 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
kevman 0:38ceb79fef03 133 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
kevman 0:38ceb79fef03 134
kevman 0:38ceb79fef03 135 end_ext_data = *p + len;
kevman 0:38ceb79fef03 136
kevman 0:38ceb79fef03 137 /* Get OID (currently ignored) */
kevman 0:38ceb79fef03 138 if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len,
kevman 0:38ceb79fef03 139 MBEDTLS_ASN1_OID ) ) != 0 )
kevman 0:38ceb79fef03 140 {
kevman 0:38ceb79fef03 141 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
kevman 0:38ceb79fef03 142 }
kevman 0:38ceb79fef03 143 *p += len;
kevman 0:38ceb79fef03 144
kevman 0:38ceb79fef03 145 /* Get optional critical */
kevman 0:38ceb79fef03 146 if( ( ret = mbedtls_asn1_get_bool( p, end_ext_data,
kevman 0:38ceb79fef03 147 &is_critical ) ) != 0 &&
kevman 0:38ceb79fef03 148 ( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) )
kevman 0:38ceb79fef03 149 {
kevman 0:38ceb79fef03 150 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
kevman 0:38ceb79fef03 151 }
kevman 0:38ceb79fef03 152
kevman 0:38ceb79fef03 153 /* Data should be octet string type */
kevman 0:38ceb79fef03 154 if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len,
kevman 0:38ceb79fef03 155 MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
kevman 0:38ceb79fef03 156 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
kevman 0:38ceb79fef03 157
kevman 0:38ceb79fef03 158 /* Ignore data so far and just check its length */
kevman 0:38ceb79fef03 159 *p += len;
kevman 0:38ceb79fef03 160 if( *p != end_ext_data )
kevman 0:38ceb79fef03 161 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
kevman 0:38ceb79fef03 162 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
kevman 0:38ceb79fef03 163
kevman 0:38ceb79fef03 164 /* Abort on (unsupported) critical extensions */
kevman 0:38ceb79fef03 165 if( is_critical )
kevman 0:38ceb79fef03 166 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
kevman 0:38ceb79fef03 167 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
kevman 0:38ceb79fef03 168 }
kevman 0:38ceb79fef03 169
kevman 0:38ceb79fef03 170 if( *p != end )
kevman 0:38ceb79fef03 171 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
kevman 0:38ceb79fef03 172 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
kevman 0:38ceb79fef03 173
kevman 0:38ceb79fef03 174 return( 0 );
kevman 0:38ceb79fef03 175 }
kevman 0:38ceb79fef03 176
kevman 0:38ceb79fef03 177 /*
kevman 0:38ceb79fef03 178 * X.509 CRL v2 entry extensions (no extensions parsed yet.)
kevman 0:38ceb79fef03 179 */
kevman 0:38ceb79fef03 180 static int x509_get_crl_entry_ext( unsigned char **p,
kevman 0:38ceb79fef03 181 const unsigned char *end,
kevman 0:38ceb79fef03 182 mbedtls_x509_buf *ext )
kevman 0:38ceb79fef03 183 {
kevman 0:38ceb79fef03 184 int ret;
kevman 0:38ceb79fef03 185 size_t len = 0;
kevman 0:38ceb79fef03 186
kevman 0:38ceb79fef03 187 /* OPTIONAL */
kevman 0:38ceb79fef03 188 if( end <= *p )
kevman 0:38ceb79fef03 189 return( 0 );
kevman 0:38ceb79fef03 190
kevman 0:38ceb79fef03 191 ext->tag = **p;
kevman 0:38ceb79fef03 192 ext->p = *p;
kevman 0:38ceb79fef03 193
kevman 0:38ceb79fef03 194 /*
kevman 0:38ceb79fef03 195 * Get CRL-entry extension sequence header
kevman 0:38ceb79fef03 196 * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2
kevman 0:38ceb79fef03 197 */
kevman 0:38ceb79fef03 198 if( ( ret = mbedtls_asn1_get_tag( p, end, &ext->len,
kevman 0:38ceb79fef03 199 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
kevman 0:38ceb79fef03 200 {
kevman 0:38ceb79fef03 201 if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
kevman 0:38ceb79fef03 202 {
kevman 0:38ceb79fef03 203 ext->p = NULL;
kevman 0:38ceb79fef03 204 return( 0 );
kevman 0:38ceb79fef03 205 }
kevman 0:38ceb79fef03 206 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
kevman 0:38ceb79fef03 207 }
kevman 0:38ceb79fef03 208
kevman 0:38ceb79fef03 209 end = *p + ext->len;
kevman 0:38ceb79fef03 210
kevman 0:38ceb79fef03 211 if( end != *p + ext->len )
kevman 0:38ceb79fef03 212 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
kevman 0:38ceb79fef03 213 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
kevman 0:38ceb79fef03 214
kevman 0:38ceb79fef03 215 while( *p < end )
kevman 0:38ceb79fef03 216 {
kevman 0:38ceb79fef03 217 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
kevman 0:38ceb79fef03 218 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
kevman 0:38ceb79fef03 219 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
kevman 0:38ceb79fef03 220
kevman 0:38ceb79fef03 221 *p += len;
kevman 0:38ceb79fef03 222 }
kevman 0:38ceb79fef03 223
kevman 0:38ceb79fef03 224 if( *p != end )
kevman 0:38ceb79fef03 225 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
kevman 0:38ceb79fef03 226 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
kevman 0:38ceb79fef03 227
kevman 0:38ceb79fef03 228 return( 0 );
kevman 0:38ceb79fef03 229 }
kevman 0:38ceb79fef03 230
kevman 0:38ceb79fef03 231 /*
kevman 0:38ceb79fef03 232 * X.509 CRL Entries
kevman 0:38ceb79fef03 233 */
kevman 0:38ceb79fef03 234 static int x509_get_entries( unsigned char **p,
kevman 0:38ceb79fef03 235 const unsigned char *end,
kevman 0:38ceb79fef03 236 mbedtls_x509_crl_entry *entry )
kevman 0:38ceb79fef03 237 {
kevman 0:38ceb79fef03 238 int ret;
kevman 0:38ceb79fef03 239 size_t entry_len;
kevman 0:38ceb79fef03 240 mbedtls_x509_crl_entry *cur_entry = entry;
kevman 0:38ceb79fef03 241
kevman 0:38ceb79fef03 242 if( *p == end )
kevman 0:38ceb79fef03 243 return( 0 );
kevman 0:38ceb79fef03 244
kevman 0:38ceb79fef03 245 if( ( ret = mbedtls_asn1_get_tag( p, end, &entry_len,
kevman 0:38ceb79fef03 246 MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED ) ) != 0 )
kevman 0:38ceb79fef03 247 {
kevman 0:38ceb79fef03 248 if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
kevman 0:38ceb79fef03 249 return( 0 );
kevman 0:38ceb79fef03 250
kevman 0:38ceb79fef03 251 return( ret );
kevman 0:38ceb79fef03 252 }
kevman 0:38ceb79fef03 253
kevman 0:38ceb79fef03 254 end = *p + entry_len;
kevman 0:38ceb79fef03 255
kevman 0:38ceb79fef03 256 while( *p < end )
kevman 0:38ceb79fef03 257 {
kevman 0:38ceb79fef03 258 size_t len2;
kevman 0:38ceb79fef03 259 const unsigned char *end2;
kevman 0:38ceb79fef03 260
kevman 0:38ceb79fef03 261 if( ( ret = mbedtls_asn1_get_tag( p, end, &len2,
kevman 0:38ceb79fef03 262 MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED ) ) != 0 )
kevman 0:38ceb79fef03 263 {
kevman 0:38ceb79fef03 264 return( ret );
kevman 0:38ceb79fef03 265 }
kevman 0:38ceb79fef03 266
kevman 0:38ceb79fef03 267 cur_entry->raw.tag = **p;
kevman 0:38ceb79fef03 268 cur_entry->raw.p = *p;
kevman 0:38ceb79fef03 269 cur_entry->raw.len = len2;
kevman 0:38ceb79fef03 270 end2 = *p + len2;
kevman 0:38ceb79fef03 271
kevman 0:38ceb79fef03 272 if( ( ret = mbedtls_x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
kevman 0:38ceb79fef03 273 return( ret );
kevman 0:38ceb79fef03 274
kevman 0:38ceb79fef03 275 if( ( ret = mbedtls_x509_get_time( p, end2,
kevman 0:38ceb79fef03 276 &cur_entry->revocation_date ) ) != 0 )
kevman 0:38ceb79fef03 277 return( ret );
kevman 0:38ceb79fef03 278
kevman 0:38ceb79fef03 279 if( ( ret = x509_get_crl_entry_ext( p, end2,
kevman 0:38ceb79fef03 280 &cur_entry->entry_ext ) ) != 0 )
kevman 0:38ceb79fef03 281 return( ret );
kevman 0:38ceb79fef03 282
kevman 0:38ceb79fef03 283 if( *p < end )
kevman 0:38ceb79fef03 284 {
kevman 0:38ceb79fef03 285 cur_entry->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crl_entry ) );
kevman 0:38ceb79fef03 286
kevman 0:38ceb79fef03 287 if( cur_entry->next == NULL )
kevman 0:38ceb79fef03 288 return( MBEDTLS_ERR_X509_ALLOC_FAILED );
kevman 0:38ceb79fef03 289
kevman 0:38ceb79fef03 290 cur_entry = cur_entry->next;
kevman 0:38ceb79fef03 291 }
kevman 0:38ceb79fef03 292 }
kevman 0:38ceb79fef03 293
kevman 0:38ceb79fef03 294 return( 0 );
kevman 0:38ceb79fef03 295 }
kevman 0:38ceb79fef03 296
kevman 0:38ceb79fef03 297 /*
kevman 0:38ceb79fef03 298 * Parse one CRLs in DER format and append it to the chained list
kevman 0:38ceb79fef03 299 */
kevman 0:38ceb79fef03 300 int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
kevman 0:38ceb79fef03 301 const unsigned char *buf, size_t buflen )
kevman 0:38ceb79fef03 302 {
kevman 0:38ceb79fef03 303 int ret;
kevman 0:38ceb79fef03 304 size_t len;
kevman 0:38ceb79fef03 305 unsigned char *p = NULL, *end = NULL;
kevman 0:38ceb79fef03 306 mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
kevman 0:38ceb79fef03 307 mbedtls_x509_crl *crl = chain;
kevman 0:38ceb79fef03 308
kevman 0:38ceb79fef03 309 /*
kevman 0:38ceb79fef03 310 * Check for valid input
kevman 0:38ceb79fef03 311 */
kevman 0:38ceb79fef03 312 if( crl == NULL || buf == NULL )
kevman 0:38ceb79fef03 313 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
kevman 0:38ceb79fef03 314
kevman 0:38ceb79fef03 315 memset( &sig_params1, 0, sizeof( mbedtls_x509_buf ) );
kevman 0:38ceb79fef03 316 memset( &sig_params2, 0, sizeof( mbedtls_x509_buf ) );
kevman 0:38ceb79fef03 317 memset( &sig_oid2, 0, sizeof( mbedtls_x509_buf ) );
kevman 0:38ceb79fef03 318
kevman 0:38ceb79fef03 319 /*
kevman 0:38ceb79fef03 320 * Add new CRL on the end of the chain if needed.
kevman 0:38ceb79fef03 321 */
kevman 0:38ceb79fef03 322 while( crl->version != 0 && crl->next != NULL )
kevman 0:38ceb79fef03 323 crl = crl->next;
kevman 0:38ceb79fef03 324
kevman 0:38ceb79fef03 325 if( crl->version != 0 && crl->next == NULL )
kevman 0:38ceb79fef03 326 {
kevman 0:38ceb79fef03 327 crl->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crl ) );
kevman 0:38ceb79fef03 328
kevman 0:38ceb79fef03 329 if( crl->next == NULL )
kevman 0:38ceb79fef03 330 {
kevman 0:38ceb79fef03 331 mbedtls_x509_crl_free( crl );
kevman 0:38ceb79fef03 332 return( MBEDTLS_ERR_X509_ALLOC_FAILED );
kevman 0:38ceb79fef03 333 }
kevman 0:38ceb79fef03 334
kevman 0:38ceb79fef03 335 mbedtls_x509_crl_init( crl->next );
kevman 0:38ceb79fef03 336 crl = crl->next;
kevman 0:38ceb79fef03 337 }
kevman 0:38ceb79fef03 338
kevman 0:38ceb79fef03 339 /*
kevman 0:38ceb79fef03 340 * Copy raw DER-encoded CRL
kevman 0:38ceb79fef03 341 */
kevman 0:38ceb79fef03 342 if( buflen == 0 )
kevman 0:38ceb79fef03 343 return( MBEDTLS_ERR_X509_INVALID_FORMAT );
kevman 0:38ceb79fef03 344
kevman 0:38ceb79fef03 345 p = mbedtls_calloc( 1, buflen );
kevman 0:38ceb79fef03 346 if( p == NULL )
kevman 0:38ceb79fef03 347 return( MBEDTLS_ERR_X509_ALLOC_FAILED );
kevman 0:38ceb79fef03 348
kevman 0:38ceb79fef03 349 memcpy( p, buf, buflen );
kevman 0:38ceb79fef03 350
kevman 0:38ceb79fef03 351 crl->raw.p = p;
kevman 0:38ceb79fef03 352 crl->raw.len = buflen;
kevman 0:38ceb79fef03 353
kevman 0:38ceb79fef03 354 end = p + buflen;
kevman 0:38ceb79fef03 355
kevman 0:38ceb79fef03 356 /*
kevman 0:38ceb79fef03 357 * CertificateList ::= SEQUENCE {
kevman 0:38ceb79fef03 358 * tbsCertList TBSCertList,
kevman 0:38ceb79fef03 359 * signatureAlgorithm AlgorithmIdentifier,
kevman 0:38ceb79fef03 360 * signatureValue BIT STRING }
kevman 0:38ceb79fef03 361 */
kevman 0:38ceb79fef03 362 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
kevman 0:38ceb79fef03 363 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
kevman 0:38ceb79fef03 364 {
kevman 0:38ceb79fef03 365 mbedtls_x509_crl_free( crl );
kevman 0:38ceb79fef03 366 return( MBEDTLS_ERR_X509_INVALID_FORMAT );
kevman 0:38ceb79fef03 367 }
kevman 0:38ceb79fef03 368
kevman 0:38ceb79fef03 369 if( len != (size_t) ( end - p ) )
kevman 0:38ceb79fef03 370 {
kevman 0:38ceb79fef03 371 mbedtls_x509_crl_free( crl );
kevman 0:38ceb79fef03 372 return( MBEDTLS_ERR_X509_INVALID_FORMAT +
kevman 0:38ceb79fef03 373 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
kevman 0:38ceb79fef03 374 }
kevman 0:38ceb79fef03 375
kevman 0:38ceb79fef03 376 /*
kevman 0:38ceb79fef03 377 * TBSCertList ::= SEQUENCE {
kevman 0:38ceb79fef03 378 */
kevman 0:38ceb79fef03 379 crl->tbs.p = p;
kevman 0:38ceb79fef03 380
kevman 0:38ceb79fef03 381 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
kevman 0:38ceb79fef03 382 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
kevman 0:38ceb79fef03 383 {
kevman 0:38ceb79fef03 384 mbedtls_x509_crl_free( crl );
kevman 0:38ceb79fef03 385 return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
kevman 0:38ceb79fef03 386 }
kevman 0:38ceb79fef03 387
kevman 0:38ceb79fef03 388 end = p + len;
kevman 0:38ceb79fef03 389 crl->tbs.len = end - crl->tbs.p;
kevman 0:38ceb79fef03 390
kevman 0:38ceb79fef03 391 /*
kevman 0:38ceb79fef03 392 * Version ::= INTEGER OPTIONAL { v1(0), v2(1) }
kevman 0:38ceb79fef03 393 * -- if present, MUST be v2
kevman 0:38ceb79fef03 394 *
kevman 0:38ceb79fef03 395 * signature AlgorithmIdentifier
kevman 0:38ceb79fef03 396 */
kevman 0:38ceb79fef03 397 if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
kevman 0:38ceb79fef03 398 ( ret = mbedtls_x509_get_alg( &p, end, &crl->sig_oid, &sig_params1 ) ) != 0 )
kevman 0:38ceb79fef03 399 {
kevman 0:38ceb79fef03 400 mbedtls_x509_crl_free( crl );
kevman 0:38ceb79fef03 401 return( ret );
kevman 0:38ceb79fef03 402 }
kevman 0:38ceb79fef03 403
kevman 0:38ceb79fef03 404 if( crl->version < 0 || crl->version > 1 )
kevman 0:38ceb79fef03 405 {
kevman 0:38ceb79fef03 406 mbedtls_x509_crl_free( crl );
kevman 0:38ceb79fef03 407 return( MBEDTLS_ERR_X509_UNKNOWN_VERSION );
kevman 0:38ceb79fef03 408 }
kevman 0:38ceb79fef03 409
kevman 0:38ceb79fef03 410 crl->version++;
kevman 0:38ceb79fef03 411
kevman 0:38ceb79fef03 412 if( ( ret = mbedtls_x509_get_sig_alg( &crl->sig_oid, &sig_params1,
kevman 0:38ceb79fef03 413 &crl->sig_md, &crl->sig_pk,
kevman 0:38ceb79fef03 414 &crl->sig_opts ) ) != 0 )
kevman 0:38ceb79fef03 415 {
kevman 0:38ceb79fef03 416 mbedtls_x509_crl_free( crl );
kevman 0:38ceb79fef03 417 return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG );
kevman 0:38ceb79fef03 418 }
kevman 0:38ceb79fef03 419
kevman 0:38ceb79fef03 420 /*
kevman 0:38ceb79fef03 421 * issuer Name
kevman 0:38ceb79fef03 422 */
kevman 0:38ceb79fef03 423 crl->issuer_raw.p = p;
kevman 0:38ceb79fef03 424
kevman 0:38ceb79fef03 425 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
kevman 0:38ceb79fef03 426 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
kevman 0:38ceb79fef03 427 {
kevman 0:38ceb79fef03 428 mbedtls_x509_crl_free( crl );
kevman 0:38ceb79fef03 429 return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
kevman 0:38ceb79fef03 430 }
kevman 0:38ceb79fef03 431
kevman 0:38ceb79fef03 432 if( ( ret = mbedtls_x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
kevman 0:38ceb79fef03 433 {
kevman 0:38ceb79fef03 434 mbedtls_x509_crl_free( crl );
kevman 0:38ceb79fef03 435 return( ret );
kevman 0:38ceb79fef03 436 }
kevman 0:38ceb79fef03 437
kevman 0:38ceb79fef03 438 crl->issuer_raw.len = p - crl->issuer_raw.p;
kevman 0:38ceb79fef03 439
kevman 0:38ceb79fef03 440 /*
kevman 0:38ceb79fef03 441 * thisUpdate Time
kevman 0:38ceb79fef03 442 * nextUpdate Time OPTIONAL
kevman 0:38ceb79fef03 443 */
kevman 0:38ceb79fef03 444 if( ( ret = mbedtls_x509_get_time( &p, end, &crl->this_update ) ) != 0 )
kevman 0:38ceb79fef03 445 {
kevman 0:38ceb79fef03 446 mbedtls_x509_crl_free( crl );
kevman 0:38ceb79fef03 447 return( ret );
kevman 0:38ceb79fef03 448 }
kevman 0:38ceb79fef03 449
kevman 0:38ceb79fef03 450 if( ( ret = mbedtls_x509_get_time( &p, end, &crl->next_update ) ) != 0 )
kevman 0:38ceb79fef03 451 {
kevman 0:38ceb79fef03 452 if( ret != ( MBEDTLS_ERR_X509_INVALID_DATE +
kevman 0:38ceb79fef03 453 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) &&
kevman 0:38ceb79fef03 454 ret != ( MBEDTLS_ERR_X509_INVALID_DATE +
kevman 0:38ceb79fef03 455 MBEDTLS_ERR_ASN1_OUT_OF_DATA ) )
kevman 0:38ceb79fef03 456 {
kevman 0:38ceb79fef03 457 mbedtls_x509_crl_free( crl );
kevman 0:38ceb79fef03 458 return( ret );
kevman 0:38ceb79fef03 459 }
kevman 0:38ceb79fef03 460 }
kevman 0:38ceb79fef03 461
kevman 0:38ceb79fef03 462 /*
kevman 0:38ceb79fef03 463 * revokedCertificates SEQUENCE OF SEQUENCE {
kevman 0:38ceb79fef03 464 * userCertificate CertificateSerialNumber,
kevman 0:38ceb79fef03 465 * revocationDate Time,
kevman 0:38ceb79fef03 466 * crlEntryExtensions Extensions OPTIONAL
kevman 0:38ceb79fef03 467 * -- if present, MUST be v2
kevman 0:38ceb79fef03 468 * } OPTIONAL
kevman 0:38ceb79fef03 469 */
kevman 0:38ceb79fef03 470 if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
kevman 0:38ceb79fef03 471 {
kevman 0:38ceb79fef03 472 mbedtls_x509_crl_free( crl );
kevman 0:38ceb79fef03 473 return( ret );
kevman 0:38ceb79fef03 474 }
kevman 0:38ceb79fef03 475
kevman 0:38ceb79fef03 476 /*
kevman 0:38ceb79fef03 477 * crlExtensions EXPLICIT Extensions OPTIONAL
kevman 0:38ceb79fef03 478 * -- if present, MUST be v2
kevman 0:38ceb79fef03 479 */
kevman 0:38ceb79fef03 480 if( crl->version == 2 )
kevman 0:38ceb79fef03 481 {
kevman 0:38ceb79fef03 482 ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
kevman 0:38ceb79fef03 483
kevman 0:38ceb79fef03 484 if( ret != 0 )
kevman 0:38ceb79fef03 485 {
kevman 0:38ceb79fef03 486 mbedtls_x509_crl_free( crl );
kevman 0:38ceb79fef03 487 return( ret );
kevman 0:38ceb79fef03 488 }
kevman 0:38ceb79fef03 489 }
kevman 0:38ceb79fef03 490
kevman 0:38ceb79fef03 491 if( p != end )
kevman 0:38ceb79fef03 492 {
kevman 0:38ceb79fef03 493 mbedtls_x509_crl_free( crl );
kevman 0:38ceb79fef03 494 return( MBEDTLS_ERR_X509_INVALID_FORMAT +
kevman 0:38ceb79fef03 495 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
kevman 0:38ceb79fef03 496 }
kevman 0:38ceb79fef03 497
kevman 0:38ceb79fef03 498 end = crl->raw.p + crl->raw.len;
kevman 0:38ceb79fef03 499
kevman 0:38ceb79fef03 500 /*
kevman 0:38ceb79fef03 501 * signatureAlgorithm AlgorithmIdentifier,
kevman 0:38ceb79fef03 502 * signatureValue BIT STRING
kevman 0:38ceb79fef03 503 */
kevman 0:38ceb79fef03 504 if( ( ret = mbedtls_x509_get_alg( &p, end, &sig_oid2, &sig_params2 ) ) != 0 )
kevman 0:38ceb79fef03 505 {
kevman 0:38ceb79fef03 506 mbedtls_x509_crl_free( crl );
kevman 0:38ceb79fef03 507 return( ret );
kevman 0:38ceb79fef03 508 }
kevman 0:38ceb79fef03 509
kevman 0:38ceb79fef03 510 if( crl->sig_oid.len != sig_oid2.len ||
kevman 0:38ceb79fef03 511 memcmp( crl->sig_oid.p, sig_oid2.p, crl->sig_oid.len ) != 0 ||
kevman 0:38ceb79fef03 512 sig_params1.len != sig_params2.len ||
kevman 0:38ceb79fef03 513 ( sig_params1.len != 0 &&
kevman 0:38ceb79fef03 514 memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
kevman 0:38ceb79fef03 515 {
kevman 0:38ceb79fef03 516 mbedtls_x509_crl_free( crl );
kevman 0:38ceb79fef03 517 return( MBEDTLS_ERR_X509_SIG_MISMATCH );
kevman 0:38ceb79fef03 518 }
kevman 0:38ceb79fef03 519
kevman 0:38ceb79fef03 520 if( ( ret = mbedtls_x509_get_sig( &p, end, &crl->sig ) ) != 0 )
kevman 0:38ceb79fef03 521 {
kevman 0:38ceb79fef03 522 mbedtls_x509_crl_free( crl );
kevman 0:38ceb79fef03 523 return( ret );
kevman 0:38ceb79fef03 524 }
kevman 0:38ceb79fef03 525
kevman 0:38ceb79fef03 526 if( p != end )
kevman 0:38ceb79fef03 527 {
kevman 0:38ceb79fef03 528 mbedtls_x509_crl_free( crl );
kevman 0:38ceb79fef03 529 return( MBEDTLS_ERR_X509_INVALID_FORMAT +
kevman 0:38ceb79fef03 530 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
kevman 0:38ceb79fef03 531 }
kevman 0:38ceb79fef03 532
kevman 0:38ceb79fef03 533 return( 0 );
kevman 0:38ceb79fef03 534 }
kevman 0:38ceb79fef03 535
kevman 0:38ceb79fef03 536 /*
kevman 0:38ceb79fef03 537 * Parse one or more CRLs and add them to the chained list
kevman 0:38ceb79fef03 538 */
kevman 0:38ceb79fef03 539 int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, size_t buflen )
kevman 0:38ceb79fef03 540 {
kevman 0:38ceb79fef03 541 #if defined(MBEDTLS_PEM_PARSE_C)
kevman 0:38ceb79fef03 542 int ret;
kevman 0:38ceb79fef03 543 size_t use_len;
kevman 0:38ceb79fef03 544 mbedtls_pem_context pem;
kevman 0:38ceb79fef03 545 int is_pem = 0;
kevman 0:38ceb79fef03 546
kevman 0:38ceb79fef03 547 if( chain == NULL || buf == NULL )
kevman 0:38ceb79fef03 548 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
kevman 0:38ceb79fef03 549
kevman 0:38ceb79fef03 550 do
kevman 0:38ceb79fef03 551 {
kevman 0:38ceb79fef03 552 mbedtls_pem_init( &pem );
kevman 0:38ceb79fef03 553
kevman 0:38ceb79fef03 554 // Avoid calling mbedtls_pem_read_buffer() on non-null-terminated
kevman 0:38ceb79fef03 555 // string
kevman 0:38ceb79fef03 556 if( buflen == 0 || buf[buflen - 1] != '\0' )
kevman 0:38ceb79fef03 557 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
kevman 0:38ceb79fef03 558 else
kevman 0:38ceb79fef03 559 ret = mbedtls_pem_read_buffer( &pem,
kevman 0:38ceb79fef03 560 "-----BEGIN X509 CRL-----",
kevman 0:38ceb79fef03 561 "-----END X509 CRL-----",
kevman 0:38ceb79fef03 562 buf, NULL, 0, &use_len );
kevman 0:38ceb79fef03 563
kevman 0:38ceb79fef03 564 if( ret == 0 )
kevman 0:38ceb79fef03 565 {
kevman 0:38ceb79fef03 566 /*
kevman 0:38ceb79fef03 567 * Was PEM encoded
kevman 0:38ceb79fef03 568 */
kevman 0:38ceb79fef03 569 is_pem = 1;
kevman 0:38ceb79fef03 570
kevman 0:38ceb79fef03 571 buflen -= use_len;
kevman 0:38ceb79fef03 572 buf += use_len;
kevman 0:38ceb79fef03 573
kevman 0:38ceb79fef03 574 if( ( ret = mbedtls_x509_crl_parse_der( chain,
kevman 0:38ceb79fef03 575 pem.buf, pem.buflen ) ) != 0 )
kevman 0:38ceb79fef03 576 {
kevman 0:38ceb79fef03 577 mbedtls_pem_free( &pem );
kevman 0:38ceb79fef03 578 return( ret );
kevman 0:38ceb79fef03 579 }
kevman 0:38ceb79fef03 580 }
kevman 0:38ceb79fef03 581 else if( is_pem )
kevman 0:38ceb79fef03 582 {
kevman 0:38ceb79fef03 583 mbedtls_pem_free( &pem );
kevman 0:38ceb79fef03 584 return( ret );
kevman 0:38ceb79fef03 585 }
kevman 0:38ceb79fef03 586
kevman 0:38ceb79fef03 587 mbedtls_pem_free( &pem );
kevman 0:38ceb79fef03 588 }
kevman 0:38ceb79fef03 589 /* In the PEM case, buflen is 1 at the end, for the terminated NULL byte.
kevman 0:38ceb79fef03 590 * And a valid CRL cannot be less than 1 byte anyway. */
kevman 0:38ceb79fef03 591 while( is_pem && buflen > 1 );
kevman 0:38ceb79fef03 592
kevman 0:38ceb79fef03 593 if( is_pem )
kevman 0:38ceb79fef03 594 return( 0 );
kevman 0:38ceb79fef03 595 else
kevman 0:38ceb79fef03 596 #endif /* MBEDTLS_PEM_PARSE_C */
kevman 0:38ceb79fef03 597 return( mbedtls_x509_crl_parse_der( chain, buf, buflen ) );
kevman 0:38ceb79fef03 598 }
kevman 0:38ceb79fef03 599
kevman 0:38ceb79fef03 600 #if defined(MBEDTLS_FS_IO)
kevman 0:38ceb79fef03 601 /*
kevman 0:38ceb79fef03 602 * Load one or more CRLs and add them to the chained list
kevman 0:38ceb79fef03 603 */
kevman 0:38ceb79fef03 604 int mbedtls_x509_crl_parse_file( mbedtls_x509_crl *chain, const char *path )
kevman 0:38ceb79fef03 605 {
kevman 0:38ceb79fef03 606 int ret;
kevman 0:38ceb79fef03 607 size_t n;
kevman 0:38ceb79fef03 608 unsigned char *buf;
kevman 0:38ceb79fef03 609
kevman 0:38ceb79fef03 610 if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
kevman 0:38ceb79fef03 611 return( ret );
kevman 0:38ceb79fef03 612
kevman 0:38ceb79fef03 613 ret = mbedtls_x509_crl_parse( chain, buf, n );
kevman 0:38ceb79fef03 614
kevman 0:38ceb79fef03 615 mbedtls_platform_zeroize( buf, n );
kevman 0:38ceb79fef03 616 mbedtls_free( buf );
kevman 0:38ceb79fef03 617
kevman 0:38ceb79fef03 618 return( ret );
kevman 0:38ceb79fef03 619 }
kevman 0:38ceb79fef03 620 #endif /* MBEDTLS_FS_IO */
kevman 0:38ceb79fef03 621
kevman 0:38ceb79fef03 622 /*
kevman 0:38ceb79fef03 623 * Return an informational string about the certificate.
kevman 0:38ceb79fef03 624 */
kevman 0:38ceb79fef03 625 #define BEFORE_COLON 14
kevman 0:38ceb79fef03 626 #define BC "14"
kevman 0:38ceb79fef03 627 /*
kevman 0:38ceb79fef03 628 * Return an informational string about the CRL.
kevman 0:38ceb79fef03 629 */
kevman 0:38ceb79fef03 630 int mbedtls_x509_crl_info( char *buf, size_t size, const char *prefix,
kevman 0:38ceb79fef03 631 const mbedtls_x509_crl *crl )
kevman 0:38ceb79fef03 632 {
kevman 0:38ceb79fef03 633 int ret;
kevman 0:38ceb79fef03 634 size_t n;
kevman 0:38ceb79fef03 635 char *p;
kevman 0:38ceb79fef03 636 const mbedtls_x509_crl_entry *entry;
kevman 0:38ceb79fef03 637
kevman 0:38ceb79fef03 638 p = buf;
kevman 0:38ceb79fef03 639 n = size;
kevman 0:38ceb79fef03 640
kevman 0:38ceb79fef03 641 ret = mbedtls_snprintf( p, n, "%sCRL version : %d",
kevman 0:38ceb79fef03 642 prefix, crl->version );
kevman 0:38ceb79fef03 643 MBEDTLS_X509_SAFE_SNPRINTF;
kevman 0:38ceb79fef03 644
kevman 0:38ceb79fef03 645 ret = mbedtls_snprintf( p, n, "\n%sissuer name : ", prefix );
kevman 0:38ceb79fef03 646 MBEDTLS_X509_SAFE_SNPRINTF;
kevman 0:38ceb79fef03 647 ret = mbedtls_x509_dn_gets( p, n, &crl->issuer );
kevman 0:38ceb79fef03 648 MBEDTLS_X509_SAFE_SNPRINTF;
kevman 0:38ceb79fef03 649
kevman 0:38ceb79fef03 650 ret = mbedtls_snprintf( p, n, "\n%sthis update : " \
kevman 0:38ceb79fef03 651 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
kevman 0:38ceb79fef03 652 crl->this_update.year, crl->this_update.mon,
kevman 0:38ceb79fef03 653 crl->this_update.day, crl->this_update.hour,
kevman 0:38ceb79fef03 654 crl->this_update.min, crl->this_update.sec );
kevman 0:38ceb79fef03 655 MBEDTLS_X509_SAFE_SNPRINTF;
kevman 0:38ceb79fef03 656
kevman 0:38ceb79fef03 657 ret = mbedtls_snprintf( p, n, "\n%snext update : " \
kevman 0:38ceb79fef03 658 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
kevman 0:38ceb79fef03 659 crl->next_update.year, crl->next_update.mon,
kevman 0:38ceb79fef03 660 crl->next_update.day, crl->next_update.hour,
kevman 0:38ceb79fef03 661 crl->next_update.min, crl->next_update.sec );
kevman 0:38ceb79fef03 662 MBEDTLS_X509_SAFE_SNPRINTF;
kevman 0:38ceb79fef03 663
kevman 0:38ceb79fef03 664 entry = &crl->entry;
kevman 0:38ceb79fef03 665
kevman 0:38ceb79fef03 666 ret = mbedtls_snprintf( p, n, "\n%sRevoked certificates:",
kevman 0:38ceb79fef03 667 prefix );
kevman 0:38ceb79fef03 668 MBEDTLS_X509_SAFE_SNPRINTF;
kevman 0:38ceb79fef03 669
kevman 0:38ceb79fef03 670 while( entry != NULL && entry->raw.len != 0 )
kevman 0:38ceb79fef03 671 {
kevman 0:38ceb79fef03 672 ret = mbedtls_snprintf( p, n, "\n%sserial number: ",
kevman 0:38ceb79fef03 673 prefix );
kevman 0:38ceb79fef03 674 MBEDTLS_X509_SAFE_SNPRINTF;
kevman 0:38ceb79fef03 675
kevman 0:38ceb79fef03 676 ret = mbedtls_x509_serial_gets( p, n, &entry->serial );
kevman 0:38ceb79fef03 677 MBEDTLS_X509_SAFE_SNPRINTF;
kevman 0:38ceb79fef03 678
kevman 0:38ceb79fef03 679 ret = mbedtls_snprintf( p, n, " revocation date: " \
kevman 0:38ceb79fef03 680 "%04d-%02d-%02d %02d:%02d:%02d",
kevman 0:38ceb79fef03 681 entry->revocation_date.year, entry->revocation_date.mon,
kevman 0:38ceb79fef03 682 entry->revocation_date.day, entry->revocation_date.hour,
kevman 0:38ceb79fef03 683 entry->revocation_date.min, entry->revocation_date.sec );
kevman 0:38ceb79fef03 684 MBEDTLS_X509_SAFE_SNPRINTF;
kevman 0:38ceb79fef03 685
kevman 0:38ceb79fef03 686 entry = entry->next;
kevman 0:38ceb79fef03 687 }
kevman 0:38ceb79fef03 688
kevman 0:38ceb79fef03 689 ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix );
kevman 0:38ceb79fef03 690 MBEDTLS_X509_SAFE_SNPRINTF;
kevman 0:38ceb79fef03 691
kevman 0:38ceb79fef03 692 ret = mbedtls_x509_sig_alg_gets( p, n, &crl->sig_oid, crl->sig_pk, crl->sig_md,
kevman 0:38ceb79fef03 693 crl->sig_opts );
kevman 0:38ceb79fef03 694 MBEDTLS_X509_SAFE_SNPRINTF;
kevman 0:38ceb79fef03 695
kevman 0:38ceb79fef03 696 ret = mbedtls_snprintf( p, n, "\n" );
kevman 0:38ceb79fef03 697 MBEDTLS_X509_SAFE_SNPRINTF;
kevman 0:38ceb79fef03 698
kevman 0:38ceb79fef03 699 return( (int) ( size - n ) );
kevman 0:38ceb79fef03 700 }
kevman 0:38ceb79fef03 701
kevman 0:38ceb79fef03 702 /*
kevman 0:38ceb79fef03 703 * Initialize a CRL chain
kevman 0:38ceb79fef03 704 */
kevman 0:38ceb79fef03 705 void mbedtls_x509_crl_init( mbedtls_x509_crl *crl )
kevman 0:38ceb79fef03 706 {
kevman 0:38ceb79fef03 707 memset( crl, 0, sizeof(mbedtls_x509_crl) );
kevman 0:38ceb79fef03 708 }
kevman 0:38ceb79fef03 709
kevman 0:38ceb79fef03 710 /*
kevman 0:38ceb79fef03 711 * Unallocate all CRL data
kevman 0:38ceb79fef03 712 */
kevman 0:38ceb79fef03 713 void mbedtls_x509_crl_free( mbedtls_x509_crl *crl )
kevman 0:38ceb79fef03 714 {
kevman 0:38ceb79fef03 715 mbedtls_x509_crl *crl_cur = crl;
kevman 0:38ceb79fef03 716 mbedtls_x509_crl *crl_prv;
kevman 0:38ceb79fef03 717 mbedtls_x509_name *name_cur;
kevman 0:38ceb79fef03 718 mbedtls_x509_name *name_prv;
kevman 0:38ceb79fef03 719 mbedtls_x509_crl_entry *entry_cur;
kevman 0:38ceb79fef03 720 mbedtls_x509_crl_entry *entry_prv;
kevman 0:38ceb79fef03 721
kevman 0:38ceb79fef03 722 if( crl == NULL )
kevman 0:38ceb79fef03 723 return;
kevman 0:38ceb79fef03 724
kevman 0:38ceb79fef03 725 do
kevman 0:38ceb79fef03 726 {
kevman 0:38ceb79fef03 727 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
kevman 0:38ceb79fef03 728 mbedtls_free( crl_cur->sig_opts );
kevman 0:38ceb79fef03 729 #endif
kevman 0:38ceb79fef03 730
kevman 0:38ceb79fef03 731 name_cur = crl_cur->issuer.next;
kevman 0:38ceb79fef03 732 while( name_cur != NULL )
kevman 0:38ceb79fef03 733 {
kevman 0:38ceb79fef03 734 name_prv = name_cur;
kevman 0:38ceb79fef03 735 name_cur = name_cur->next;
kevman 0:38ceb79fef03 736 mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
kevman 0:38ceb79fef03 737 mbedtls_free( name_prv );
kevman 0:38ceb79fef03 738 }
kevman 0:38ceb79fef03 739
kevman 0:38ceb79fef03 740 entry_cur = crl_cur->entry.next;
kevman 0:38ceb79fef03 741 while( entry_cur != NULL )
kevman 0:38ceb79fef03 742 {
kevman 0:38ceb79fef03 743 entry_prv = entry_cur;
kevman 0:38ceb79fef03 744 entry_cur = entry_cur->next;
kevman 0:38ceb79fef03 745 mbedtls_platform_zeroize( entry_prv,
kevman 0:38ceb79fef03 746 sizeof( mbedtls_x509_crl_entry ) );
kevman 0:38ceb79fef03 747 mbedtls_free( entry_prv );
kevman 0:38ceb79fef03 748 }
kevman 0:38ceb79fef03 749
kevman 0:38ceb79fef03 750 if( crl_cur->raw.p != NULL )
kevman 0:38ceb79fef03 751 {
kevman 0:38ceb79fef03 752 mbedtls_platform_zeroize( crl_cur->raw.p, crl_cur->raw.len );
kevman 0:38ceb79fef03 753 mbedtls_free( crl_cur->raw.p );
kevman 0:38ceb79fef03 754 }
kevman 0:38ceb79fef03 755
kevman 0:38ceb79fef03 756 crl_cur = crl_cur->next;
kevman 0:38ceb79fef03 757 }
kevman 0:38ceb79fef03 758 while( crl_cur != NULL );
kevman 0:38ceb79fef03 759
kevman 0:38ceb79fef03 760 crl_cur = crl;
kevman 0:38ceb79fef03 761 do
kevman 0:38ceb79fef03 762 {
kevman 0:38ceb79fef03 763 crl_prv = crl_cur;
kevman 0:38ceb79fef03 764 crl_cur = crl_cur->next;
kevman 0:38ceb79fef03 765
kevman 0:38ceb79fef03 766 mbedtls_platform_zeroize( crl_prv, sizeof( mbedtls_x509_crl ) );
kevman 0:38ceb79fef03 767 if( crl_prv != crl )
kevman 0:38ceb79fef03 768 mbedtls_free( crl_prv );
kevman 0:38ceb79fef03 769 }
kevman 0:38ceb79fef03 770 while( crl_cur != NULL );
kevman 0:38ceb79fef03 771 }
kevman 0:38ceb79fef03 772
kevman 0:38ceb79fef03 773 #endif /* MBEDTLS_X509_CRL_PARSE_C */