Preliminary main mbed library for nexpaq development

Committer:
nexpaq
Date:
Fri Nov 04 20:27:58 2016 +0000
Revision:
0:6c56fb4bc5f0
Moving to library for sharing updates

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nexpaq 0:6c56fb4bc5f0 1 /*
nexpaq 0:6c56fb4bc5f0 2 * X.509 Certificate Signing Request (CSR) parsing
nexpaq 0:6c56fb4bc5f0 3 *
nexpaq 0:6c56fb4bc5f0 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
nexpaq 0:6c56fb4bc5f0 5 * SPDX-License-Identifier: Apache-2.0
nexpaq 0:6c56fb4bc5f0 6 *
nexpaq 0:6c56fb4bc5f0 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
nexpaq 0:6c56fb4bc5f0 8 * not use this file except in compliance with the License.
nexpaq 0:6c56fb4bc5f0 9 * You may obtain a copy of the License at
nexpaq 0:6c56fb4bc5f0 10 *
nexpaq 0:6c56fb4bc5f0 11 * http://www.apache.org/licenses/LICENSE-2.0
nexpaq 0:6c56fb4bc5f0 12 *
nexpaq 0:6c56fb4bc5f0 13 * Unless required by applicable law or agreed to in writing, software
nexpaq 0:6c56fb4bc5f0 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
nexpaq 0:6c56fb4bc5f0 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
nexpaq 0:6c56fb4bc5f0 16 * See the License for the specific language governing permissions and
nexpaq 0:6c56fb4bc5f0 17 * limitations under the License.
nexpaq 0:6c56fb4bc5f0 18 *
nexpaq 0:6c56fb4bc5f0 19 * This file is part of mbed TLS (https://tls.mbed.org)
nexpaq 0:6c56fb4bc5f0 20 */
nexpaq 0:6c56fb4bc5f0 21 /*
nexpaq 0:6c56fb4bc5f0 22 * The ITU-T X.509 standard defines a certificate format for PKI.
nexpaq 0:6c56fb4bc5f0 23 *
nexpaq 0:6c56fb4bc5f0 24 * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
nexpaq 0:6c56fb4bc5f0 25 * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
nexpaq 0:6c56fb4bc5f0 26 * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
nexpaq 0:6c56fb4bc5f0 27 *
nexpaq 0:6c56fb4bc5f0 28 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
nexpaq 0:6c56fb4bc5f0 29 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
nexpaq 0:6c56fb4bc5f0 30 */
nexpaq 0:6c56fb4bc5f0 31
nexpaq 0:6c56fb4bc5f0 32 #if !defined(MBEDTLS_CONFIG_FILE)
nexpaq 0:6c56fb4bc5f0 33 #include "mbedtls/config.h"
nexpaq 0:6c56fb4bc5f0 34 #else
nexpaq 0:6c56fb4bc5f0 35 #include MBEDTLS_CONFIG_FILE
nexpaq 0:6c56fb4bc5f0 36 #endif
nexpaq 0:6c56fb4bc5f0 37
nexpaq 0:6c56fb4bc5f0 38 #if defined(MBEDTLS_X509_CSR_PARSE_C)
nexpaq 0:6c56fb4bc5f0 39
nexpaq 0:6c56fb4bc5f0 40 #include "mbedtls/x509_csr.h"
nexpaq 0:6c56fb4bc5f0 41 #include "mbedtls/oid.h"
nexpaq 0:6c56fb4bc5f0 42
nexpaq 0:6c56fb4bc5f0 43 #include <string.h>
nexpaq 0:6c56fb4bc5f0 44
nexpaq 0:6c56fb4bc5f0 45 #if defined(MBEDTLS_PEM_PARSE_C)
nexpaq 0:6c56fb4bc5f0 46 #include "mbedtls/pem.h"
nexpaq 0:6c56fb4bc5f0 47 #endif
nexpaq 0:6c56fb4bc5f0 48
nexpaq 0:6c56fb4bc5f0 49 #if defined(MBEDTLS_PLATFORM_C)
nexpaq 0:6c56fb4bc5f0 50 #include "mbedtls/platform.h"
nexpaq 0:6c56fb4bc5f0 51 #else
nexpaq 0:6c56fb4bc5f0 52 #include <stdlib.h>
nexpaq 0:6c56fb4bc5f0 53 #include <stdio.h>
nexpaq 0:6c56fb4bc5f0 54 #define mbedtls_free free
nexpaq 0:6c56fb4bc5f0 55 #define mbedtls_calloc calloc
nexpaq 0:6c56fb4bc5f0 56 #define mbedtls_snprintf snprintf
nexpaq 0:6c56fb4bc5f0 57 #endif
nexpaq 0:6c56fb4bc5f0 58
nexpaq 0:6c56fb4bc5f0 59 #if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32)
nexpaq 0:6c56fb4bc5f0 60 #include <stdio.h>
nexpaq 0:6c56fb4bc5f0 61 #endif
nexpaq 0:6c56fb4bc5f0 62
nexpaq 0:6c56fb4bc5f0 63 /* Implementation that should never be optimized out by the compiler */
nexpaq 0:6c56fb4bc5f0 64 static void mbedtls_zeroize( void *v, size_t n ) {
nexpaq 0:6c56fb4bc5f0 65 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
nexpaq 0:6c56fb4bc5f0 66 }
nexpaq 0:6c56fb4bc5f0 67
nexpaq 0:6c56fb4bc5f0 68 /*
nexpaq 0:6c56fb4bc5f0 69 * Version ::= INTEGER { v1(0) }
nexpaq 0:6c56fb4bc5f0 70 */
nexpaq 0:6c56fb4bc5f0 71 static int x509_csr_get_version( unsigned char **p,
nexpaq 0:6c56fb4bc5f0 72 const unsigned char *end,
nexpaq 0:6c56fb4bc5f0 73 int *ver )
nexpaq 0:6c56fb4bc5f0 74 {
nexpaq 0:6c56fb4bc5f0 75 int ret;
nexpaq 0:6c56fb4bc5f0 76
nexpaq 0:6c56fb4bc5f0 77 if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 78 {
nexpaq 0:6c56fb4bc5f0 79 if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
nexpaq 0:6c56fb4bc5f0 80 {
nexpaq 0:6c56fb4bc5f0 81 *ver = 0;
nexpaq 0:6c56fb4bc5f0 82 return( 0 );
nexpaq 0:6c56fb4bc5f0 83 }
nexpaq 0:6c56fb4bc5f0 84
nexpaq 0:6c56fb4bc5f0 85 return( MBEDTLS_ERR_X509_INVALID_VERSION + ret );
nexpaq 0:6c56fb4bc5f0 86 }
nexpaq 0:6c56fb4bc5f0 87
nexpaq 0:6c56fb4bc5f0 88 return( 0 );
nexpaq 0:6c56fb4bc5f0 89 }
nexpaq 0:6c56fb4bc5f0 90
nexpaq 0:6c56fb4bc5f0 91 /*
nexpaq 0:6c56fb4bc5f0 92 * Parse a CSR in DER format
nexpaq 0:6c56fb4bc5f0 93 */
nexpaq 0:6c56fb4bc5f0 94 int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
nexpaq 0:6c56fb4bc5f0 95 const unsigned char *buf, size_t buflen )
nexpaq 0:6c56fb4bc5f0 96 {
nexpaq 0:6c56fb4bc5f0 97 int ret;
nexpaq 0:6c56fb4bc5f0 98 size_t len;
nexpaq 0:6c56fb4bc5f0 99 unsigned char *p, *end;
nexpaq 0:6c56fb4bc5f0 100 mbedtls_x509_buf sig_params;
nexpaq 0:6c56fb4bc5f0 101
nexpaq 0:6c56fb4bc5f0 102 memset( &sig_params, 0, sizeof( mbedtls_x509_buf ) );
nexpaq 0:6c56fb4bc5f0 103
nexpaq 0:6c56fb4bc5f0 104 /*
nexpaq 0:6c56fb4bc5f0 105 * Check for valid input
nexpaq 0:6c56fb4bc5f0 106 */
nexpaq 0:6c56fb4bc5f0 107 if( csr == NULL || buf == NULL || buflen == 0 )
nexpaq 0:6c56fb4bc5f0 108 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
nexpaq 0:6c56fb4bc5f0 109
nexpaq 0:6c56fb4bc5f0 110 mbedtls_x509_csr_init( csr );
nexpaq 0:6c56fb4bc5f0 111
nexpaq 0:6c56fb4bc5f0 112 /*
nexpaq 0:6c56fb4bc5f0 113 * first copy the raw DER data
nexpaq 0:6c56fb4bc5f0 114 */
nexpaq 0:6c56fb4bc5f0 115 p = mbedtls_calloc( 1, len = buflen );
nexpaq 0:6c56fb4bc5f0 116
nexpaq 0:6c56fb4bc5f0 117 if( p == NULL )
nexpaq 0:6c56fb4bc5f0 118 return( MBEDTLS_ERR_X509_ALLOC_FAILED );
nexpaq 0:6c56fb4bc5f0 119
nexpaq 0:6c56fb4bc5f0 120 memcpy( p, buf, buflen );
nexpaq 0:6c56fb4bc5f0 121
nexpaq 0:6c56fb4bc5f0 122 csr->raw.p = p;
nexpaq 0:6c56fb4bc5f0 123 csr->raw.len = len;
nexpaq 0:6c56fb4bc5f0 124 end = p + len;
nexpaq 0:6c56fb4bc5f0 125
nexpaq 0:6c56fb4bc5f0 126 /*
nexpaq 0:6c56fb4bc5f0 127 * CertificationRequest ::= SEQUENCE {
nexpaq 0:6c56fb4bc5f0 128 * certificationRequestInfo CertificationRequestInfo,
nexpaq 0:6c56fb4bc5f0 129 * signatureAlgorithm AlgorithmIdentifier,
nexpaq 0:6c56fb4bc5f0 130 * signature BIT STRING
nexpaq 0:6c56fb4bc5f0 131 * }
nexpaq 0:6c56fb4bc5f0 132 */
nexpaq 0:6c56fb4bc5f0 133 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
nexpaq 0:6c56fb4bc5f0 134 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 135 {
nexpaq 0:6c56fb4bc5f0 136 mbedtls_x509_csr_free( csr );
nexpaq 0:6c56fb4bc5f0 137 return( MBEDTLS_ERR_X509_INVALID_FORMAT );
nexpaq 0:6c56fb4bc5f0 138 }
nexpaq 0:6c56fb4bc5f0 139
nexpaq 0:6c56fb4bc5f0 140 if( len != (size_t) ( end - p ) )
nexpaq 0:6c56fb4bc5f0 141 {
nexpaq 0:6c56fb4bc5f0 142 mbedtls_x509_csr_free( csr );
nexpaq 0:6c56fb4bc5f0 143 return( MBEDTLS_ERR_X509_INVALID_FORMAT +
nexpaq 0:6c56fb4bc5f0 144 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
nexpaq 0:6c56fb4bc5f0 145 }
nexpaq 0:6c56fb4bc5f0 146
nexpaq 0:6c56fb4bc5f0 147 /*
nexpaq 0:6c56fb4bc5f0 148 * CertificationRequestInfo ::= SEQUENCE {
nexpaq 0:6c56fb4bc5f0 149 */
nexpaq 0:6c56fb4bc5f0 150 csr->cri.p = p;
nexpaq 0:6c56fb4bc5f0 151
nexpaq 0:6c56fb4bc5f0 152 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
nexpaq 0:6c56fb4bc5f0 153 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 154 {
nexpaq 0:6c56fb4bc5f0 155 mbedtls_x509_csr_free( csr );
nexpaq 0:6c56fb4bc5f0 156 return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
nexpaq 0:6c56fb4bc5f0 157 }
nexpaq 0:6c56fb4bc5f0 158
nexpaq 0:6c56fb4bc5f0 159 end = p + len;
nexpaq 0:6c56fb4bc5f0 160 csr->cri.len = end - csr->cri.p;
nexpaq 0:6c56fb4bc5f0 161
nexpaq 0:6c56fb4bc5f0 162 /*
nexpaq 0:6c56fb4bc5f0 163 * Version ::= INTEGER { v1(0) }
nexpaq 0:6c56fb4bc5f0 164 */
nexpaq 0:6c56fb4bc5f0 165 if( ( ret = x509_csr_get_version( &p, end, &csr->version ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 166 {
nexpaq 0:6c56fb4bc5f0 167 mbedtls_x509_csr_free( csr );
nexpaq 0:6c56fb4bc5f0 168 return( ret );
nexpaq 0:6c56fb4bc5f0 169 }
nexpaq 0:6c56fb4bc5f0 170
nexpaq 0:6c56fb4bc5f0 171 csr->version++;
nexpaq 0:6c56fb4bc5f0 172
nexpaq 0:6c56fb4bc5f0 173 if( csr->version != 1 )
nexpaq 0:6c56fb4bc5f0 174 {
nexpaq 0:6c56fb4bc5f0 175 mbedtls_x509_csr_free( csr );
nexpaq 0:6c56fb4bc5f0 176 return( MBEDTLS_ERR_X509_UNKNOWN_VERSION );
nexpaq 0:6c56fb4bc5f0 177 }
nexpaq 0:6c56fb4bc5f0 178
nexpaq 0:6c56fb4bc5f0 179 /*
nexpaq 0:6c56fb4bc5f0 180 * subject Name
nexpaq 0:6c56fb4bc5f0 181 */
nexpaq 0:6c56fb4bc5f0 182 csr->subject_raw.p = p;
nexpaq 0:6c56fb4bc5f0 183
nexpaq 0:6c56fb4bc5f0 184 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
nexpaq 0:6c56fb4bc5f0 185 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 186 {
nexpaq 0:6c56fb4bc5f0 187 mbedtls_x509_csr_free( csr );
nexpaq 0:6c56fb4bc5f0 188 return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
nexpaq 0:6c56fb4bc5f0 189 }
nexpaq 0:6c56fb4bc5f0 190
nexpaq 0:6c56fb4bc5f0 191 if( ( ret = mbedtls_x509_get_name( &p, p + len, &csr->subject ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 192 {
nexpaq 0:6c56fb4bc5f0 193 mbedtls_x509_csr_free( csr );
nexpaq 0:6c56fb4bc5f0 194 return( ret );
nexpaq 0:6c56fb4bc5f0 195 }
nexpaq 0:6c56fb4bc5f0 196
nexpaq 0:6c56fb4bc5f0 197 csr->subject_raw.len = p - csr->subject_raw.p;
nexpaq 0:6c56fb4bc5f0 198
nexpaq 0:6c56fb4bc5f0 199 /*
nexpaq 0:6c56fb4bc5f0 200 * subjectPKInfo SubjectPublicKeyInfo
nexpaq 0:6c56fb4bc5f0 201 */
nexpaq 0:6c56fb4bc5f0 202 if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &csr->pk ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 203 {
nexpaq 0:6c56fb4bc5f0 204 mbedtls_x509_csr_free( csr );
nexpaq 0:6c56fb4bc5f0 205 return( ret );
nexpaq 0:6c56fb4bc5f0 206 }
nexpaq 0:6c56fb4bc5f0 207
nexpaq 0:6c56fb4bc5f0 208 /*
nexpaq 0:6c56fb4bc5f0 209 * attributes [0] Attributes
nexpaq 0:6c56fb4bc5f0 210 *
nexpaq 0:6c56fb4bc5f0 211 * The list of possible attributes is open-ended, though RFC 2985
nexpaq 0:6c56fb4bc5f0 212 * (PKCS#9) defines a few in section 5.4. We currently don't support any,
nexpaq 0:6c56fb4bc5f0 213 * so we just ignore them. This is a safe thing to do as the worst thing
nexpaq 0:6c56fb4bc5f0 214 * that could happen is that we issue a certificate that does not match
nexpaq 0:6c56fb4bc5f0 215 * the requester's expectations - this cannot cause a violation of our
nexpaq 0:6c56fb4bc5f0 216 * signature policies.
nexpaq 0:6c56fb4bc5f0 217 */
nexpaq 0:6c56fb4bc5f0 218 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
nexpaq 0:6c56fb4bc5f0 219 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 220 {
nexpaq 0:6c56fb4bc5f0 221 mbedtls_x509_csr_free( csr );
nexpaq 0:6c56fb4bc5f0 222 return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
nexpaq 0:6c56fb4bc5f0 223 }
nexpaq 0:6c56fb4bc5f0 224
nexpaq 0:6c56fb4bc5f0 225 p += len;
nexpaq 0:6c56fb4bc5f0 226
nexpaq 0:6c56fb4bc5f0 227 end = csr->raw.p + csr->raw.len;
nexpaq 0:6c56fb4bc5f0 228
nexpaq 0:6c56fb4bc5f0 229 /*
nexpaq 0:6c56fb4bc5f0 230 * signatureAlgorithm AlgorithmIdentifier,
nexpaq 0:6c56fb4bc5f0 231 * signature BIT STRING
nexpaq 0:6c56fb4bc5f0 232 */
nexpaq 0:6c56fb4bc5f0 233 if( ( ret = mbedtls_x509_get_alg( &p, end, &csr->sig_oid, &sig_params ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 234 {
nexpaq 0:6c56fb4bc5f0 235 mbedtls_x509_csr_free( csr );
nexpaq 0:6c56fb4bc5f0 236 return( ret );
nexpaq 0:6c56fb4bc5f0 237 }
nexpaq 0:6c56fb4bc5f0 238
nexpaq 0:6c56fb4bc5f0 239 if( ( ret = mbedtls_x509_get_sig_alg( &csr->sig_oid, &sig_params,
nexpaq 0:6c56fb4bc5f0 240 &csr->sig_md, &csr->sig_pk,
nexpaq 0:6c56fb4bc5f0 241 &csr->sig_opts ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 242 {
nexpaq 0:6c56fb4bc5f0 243 mbedtls_x509_csr_free( csr );
nexpaq 0:6c56fb4bc5f0 244 return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG );
nexpaq 0:6c56fb4bc5f0 245 }
nexpaq 0:6c56fb4bc5f0 246
nexpaq 0:6c56fb4bc5f0 247 if( ( ret = mbedtls_x509_get_sig( &p, end, &csr->sig ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 248 {
nexpaq 0:6c56fb4bc5f0 249 mbedtls_x509_csr_free( csr );
nexpaq 0:6c56fb4bc5f0 250 return( ret );
nexpaq 0:6c56fb4bc5f0 251 }
nexpaq 0:6c56fb4bc5f0 252
nexpaq 0:6c56fb4bc5f0 253 if( p != end )
nexpaq 0:6c56fb4bc5f0 254 {
nexpaq 0:6c56fb4bc5f0 255 mbedtls_x509_csr_free( csr );
nexpaq 0:6c56fb4bc5f0 256 return( MBEDTLS_ERR_X509_INVALID_FORMAT +
nexpaq 0:6c56fb4bc5f0 257 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
nexpaq 0:6c56fb4bc5f0 258 }
nexpaq 0:6c56fb4bc5f0 259
nexpaq 0:6c56fb4bc5f0 260 return( 0 );
nexpaq 0:6c56fb4bc5f0 261 }
nexpaq 0:6c56fb4bc5f0 262
nexpaq 0:6c56fb4bc5f0 263 /*
nexpaq 0:6c56fb4bc5f0 264 * Parse a CSR, allowing for PEM or raw DER encoding
nexpaq 0:6c56fb4bc5f0 265 */
nexpaq 0:6c56fb4bc5f0 266 int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen )
nexpaq 0:6c56fb4bc5f0 267 {
nexpaq 0:6c56fb4bc5f0 268 int ret;
nexpaq 0:6c56fb4bc5f0 269 #if defined(MBEDTLS_PEM_PARSE_C)
nexpaq 0:6c56fb4bc5f0 270 size_t use_len;
nexpaq 0:6c56fb4bc5f0 271 mbedtls_pem_context pem;
nexpaq 0:6c56fb4bc5f0 272 #endif
nexpaq 0:6c56fb4bc5f0 273
nexpaq 0:6c56fb4bc5f0 274 /*
nexpaq 0:6c56fb4bc5f0 275 * Check for valid input
nexpaq 0:6c56fb4bc5f0 276 */
nexpaq 0:6c56fb4bc5f0 277 if( csr == NULL || buf == NULL || buflen == 0 )
nexpaq 0:6c56fb4bc5f0 278 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
nexpaq 0:6c56fb4bc5f0 279
nexpaq 0:6c56fb4bc5f0 280 #if defined(MBEDTLS_PEM_PARSE_C)
nexpaq 0:6c56fb4bc5f0 281 mbedtls_pem_init( &pem );
nexpaq 0:6c56fb4bc5f0 282
nexpaq 0:6c56fb4bc5f0 283 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
nexpaq 0:6c56fb4bc5f0 284 if( buf[buflen - 1] != '\0' )
nexpaq 0:6c56fb4bc5f0 285 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
nexpaq 0:6c56fb4bc5f0 286 else
nexpaq 0:6c56fb4bc5f0 287 ret = mbedtls_pem_read_buffer( &pem,
nexpaq 0:6c56fb4bc5f0 288 "-----BEGIN CERTIFICATE REQUEST-----",
nexpaq 0:6c56fb4bc5f0 289 "-----END CERTIFICATE REQUEST-----",
nexpaq 0:6c56fb4bc5f0 290 buf, NULL, 0, &use_len );
nexpaq 0:6c56fb4bc5f0 291
nexpaq 0:6c56fb4bc5f0 292 if( ret == 0 )
nexpaq 0:6c56fb4bc5f0 293 {
nexpaq 0:6c56fb4bc5f0 294 /*
nexpaq 0:6c56fb4bc5f0 295 * Was PEM encoded, parse the result
nexpaq 0:6c56fb4bc5f0 296 */
nexpaq 0:6c56fb4bc5f0 297 if( ( ret = mbedtls_x509_csr_parse_der( csr, pem.buf, pem.buflen ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 298 return( ret );
nexpaq 0:6c56fb4bc5f0 299
nexpaq 0:6c56fb4bc5f0 300 mbedtls_pem_free( &pem );
nexpaq 0:6c56fb4bc5f0 301 return( 0 );
nexpaq 0:6c56fb4bc5f0 302 }
nexpaq 0:6c56fb4bc5f0 303 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
nexpaq 0:6c56fb4bc5f0 304 {
nexpaq 0:6c56fb4bc5f0 305 mbedtls_pem_free( &pem );
nexpaq 0:6c56fb4bc5f0 306 return( ret );
nexpaq 0:6c56fb4bc5f0 307 }
nexpaq 0:6c56fb4bc5f0 308 else
nexpaq 0:6c56fb4bc5f0 309 #endif /* MBEDTLS_PEM_PARSE_C */
nexpaq 0:6c56fb4bc5f0 310 return( mbedtls_x509_csr_parse_der( csr, buf, buflen ) );
nexpaq 0:6c56fb4bc5f0 311 }
nexpaq 0:6c56fb4bc5f0 312
nexpaq 0:6c56fb4bc5f0 313 #if defined(MBEDTLS_FS_IO)
nexpaq 0:6c56fb4bc5f0 314 /*
nexpaq 0:6c56fb4bc5f0 315 * Load a CSR into the structure
nexpaq 0:6c56fb4bc5f0 316 */
nexpaq 0:6c56fb4bc5f0 317 int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path )
nexpaq 0:6c56fb4bc5f0 318 {
nexpaq 0:6c56fb4bc5f0 319 int ret;
nexpaq 0:6c56fb4bc5f0 320 size_t n;
nexpaq 0:6c56fb4bc5f0 321 unsigned char *buf;
nexpaq 0:6c56fb4bc5f0 322
nexpaq 0:6c56fb4bc5f0 323 if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 324 return( ret );
nexpaq 0:6c56fb4bc5f0 325
nexpaq 0:6c56fb4bc5f0 326 ret = mbedtls_x509_csr_parse( csr, buf, n );
nexpaq 0:6c56fb4bc5f0 327
nexpaq 0:6c56fb4bc5f0 328 mbedtls_zeroize( buf, n );
nexpaq 0:6c56fb4bc5f0 329 mbedtls_free( buf );
nexpaq 0:6c56fb4bc5f0 330
nexpaq 0:6c56fb4bc5f0 331 return( ret );
nexpaq 0:6c56fb4bc5f0 332 }
nexpaq 0:6c56fb4bc5f0 333 #endif /* MBEDTLS_FS_IO */
nexpaq 0:6c56fb4bc5f0 334
nexpaq 0:6c56fb4bc5f0 335 #define BEFORE_COLON 14
nexpaq 0:6c56fb4bc5f0 336 #define BC "14"
nexpaq 0:6c56fb4bc5f0 337 /*
nexpaq 0:6c56fb4bc5f0 338 * Return an informational string about the CSR.
nexpaq 0:6c56fb4bc5f0 339 */
nexpaq 0:6c56fb4bc5f0 340 int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix,
nexpaq 0:6c56fb4bc5f0 341 const mbedtls_x509_csr *csr )
nexpaq 0:6c56fb4bc5f0 342 {
nexpaq 0:6c56fb4bc5f0 343 int ret;
nexpaq 0:6c56fb4bc5f0 344 size_t n;
nexpaq 0:6c56fb4bc5f0 345 char *p;
nexpaq 0:6c56fb4bc5f0 346 char key_size_str[BEFORE_COLON];
nexpaq 0:6c56fb4bc5f0 347
nexpaq 0:6c56fb4bc5f0 348 p = buf;
nexpaq 0:6c56fb4bc5f0 349 n = size;
nexpaq 0:6c56fb4bc5f0 350
nexpaq 0:6c56fb4bc5f0 351 ret = mbedtls_snprintf( p, n, "%sCSR version : %d",
nexpaq 0:6c56fb4bc5f0 352 prefix, csr->version );
nexpaq 0:6c56fb4bc5f0 353 MBEDTLS_X509_SAFE_SNPRINTF;
nexpaq 0:6c56fb4bc5f0 354
nexpaq 0:6c56fb4bc5f0 355 ret = mbedtls_snprintf( p, n, "\n%ssubject name : ", prefix );
nexpaq 0:6c56fb4bc5f0 356 MBEDTLS_X509_SAFE_SNPRINTF;
nexpaq 0:6c56fb4bc5f0 357 ret = mbedtls_x509_dn_gets( p, n, &csr->subject );
nexpaq 0:6c56fb4bc5f0 358 MBEDTLS_X509_SAFE_SNPRINTF;
nexpaq 0:6c56fb4bc5f0 359
nexpaq 0:6c56fb4bc5f0 360 ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix );
nexpaq 0:6c56fb4bc5f0 361 MBEDTLS_X509_SAFE_SNPRINTF;
nexpaq 0:6c56fb4bc5f0 362
nexpaq 0:6c56fb4bc5f0 363 ret = mbedtls_x509_sig_alg_gets( p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md,
nexpaq 0:6c56fb4bc5f0 364 csr->sig_opts );
nexpaq 0:6c56fb4bc5f0 365 MBEDTLS_X509_SAFE_SNPRINTF;
nexpaq 0:6c56fb4bc5f0 366
nexpaq 0:6c56fb4bc5f0 367 if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON,
nexpaq 0:6c56fb4bc5f0 368 mbedtls_pk_get_name( &csr->pk ) ) ) != 0 )
nexpaq 0:6c56fb4bc5f0 369 {
nexpaq 0:6c56fb4bc5f0 370 return( ret );
nexpaq 0:6c56fb4bc5f0 371 }
nexpaq 0:6c56fb4bc5f0 372
nexpaq 0:6c56fb4bc5f0 373 ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str,
nexpaq 0:6c56fb4bc5f0 374 (int) mbedtls_pk_get_bitlen( &csr->pk ) );
nexpaq 0:6c56fb4bc5f0 375 MBEDTLS_X509_SAFE_SNPRINTF;
nexpaq 0:6c56fb4bc5f0 376
nexpaq 0:6c56fb4bc5f0 377 return( (int) ( size - n ) );
nexpaq 0:6c56fb4bc5f0 378 }
nexpaq 0:6c56fb4bc5f0 379
nexpaq 0:6c56fb4bc5f0 380 /*
nexpaq 0:6c56fb4bc5f0 381 * Initialize a CSR
nexpaq 0:6c56fb4bc5f0 382 */
nexpaq 0:6c56fb4bc5f0 383 void mbedtls_x509_csr_init( mbedtls_x509_csr *csr )
nexpaq 0:6c56fb4bc5f0 384 {
nexpaq 0:6c56fb4bc5f0 385 memset( csr, 0, sizeof(mbedtls_x509_csr) );
nexpaq 0:6c56fb4bc5f0 386 }
nexpaq 0:6c56fb4bc5f0 387
nexpaq 0:6c56fb4bc5f0 388 /*
nexpaq 0:6c56fb4bc5f0 389 * Unallocate all CSR data
nexpaq 0:6c56fb4bc5f0 390 */
nexpaq 0:6c56fb4bc5f0 391 void mbedtls_x509_csr_free( mbedtls_x509_csr *csr )
nexpaq 0:6c56fb4bc5f0 392 {
nexpaq 0:6c56fb4bc5f0 393 mbedtls_x509_name *name_cur;
nexpaq 0:6c56fb4bc5f0 394 mbedtls_x509_name *name_prv;
nexpaq 0:6c56fb4bc5f0 395
nexpaq 0:6c56fb4bc5f0 396 if( csr == NULL )
nexpaq 0:6c56fb4bc5f0 397 return;
nexpaq 0:6c56fb4bc5f0 398
nexpaq 0:6c56fb4bc5f0 399 mbedtls_pk_free( &csr->pk );
nexpaq 0:6c56fb4bc5f0 400
nexpaq 0:6c56fb4bc5f0 401 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
nexpaq 0:6c56fb4bc5f0 402 mbedtls_free( csr->sig_opts );
nexpaq 0:6c56fb4bc5f0 403 #endif
nexpaq 0:6c56fb4bc5f0 404
nexpaq 0:6c56fb4bc5f0 405 name_cur = csr->subject.next;
nexpaq 0:6c56fb4bc5f0 406 while( name_cur != NULL )
nexpaq 0:6c56fb4bc5f0 407 {
nexpaq 0:6c56fb4bc5f0 408 name_prv = name_cur;
nexpaq 0:6c56fb4bc5f0 409 name_cur = name_cur->next;
nexpaq 0:6c56fb4bc5f0 410 mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
nexpaq 0:6c56fb4bc5f0 411 mbedtls_free( name_prv );
nexpaq 0:6c56fb4bc5f0 412 }
nexpaq 0:6c56fb4bc5f0 413
nexpaq 0:6c56fb4bc5f0 414 if( csr->raw.p != NULL )
nexpaq 0:6c56fb4bc5f0 415 {
nexpaq 0:6c56fb4bc5f0 416 mbedtls_zeroize( csr->raw.p, csr->raw.len );
nexpaq 0:6c56fb4bc5f0 417 mbedtls_free( csr->raw.p );
nexpaq 0:6c56fb4bc5f0 418 }
nexpaq 0:6c56fb4bc5f0 419
nexpaq 0:6c56fb4bc5f0 420 mbedtls_zeroize( csr, sizeof( mbedtls_x509_csr ) );
nexpaq 0:6c56fb4bc5f0 421 }
nexpaq 0:6c56fb4bc5f0 422
nexpaq 0:6c56fb4bc5f0 423 #endif /* MBEDTLS_X509_CSR_PARSE_C */