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