mbed TLS library
Dependents: HTTPClient-SSL WS_SERVER
x509_csr.c
00001 /* 00002 * X.509 Certificate Signing Request (CSR) parsing 00003 * 00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved 00005 * 00006 * This file is part of mbed TLS (https://tls.mbed.org) 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License along 00019 * with this program; if not, write to the Free Software Foundation, Inc., 00020 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00021 */ 00022 /* 00023 * The ITU-T X.509 standard defines a certificate format for PKI. 00024 * 00025 * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) 00026 * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) 00027 * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) 00028 * 00029 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf 00030 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf 00031 */ 00032 00033 #if !defined(POLARSSL_CONFIG_FILE) 00034 #include "polarssl/config.h" 00035 #else 00036 #include POLARSSL_CONFIG_FILE 00037 #endif 00038 00039 #if defined(POLARSSL_X509_CSR_PARSE_C) 00040 00041 #include "polarssl/x509_csr.h" 00042 #include "polarssl/oid.h" 00043 00044 #include <string.h> 00045 00046 #if defined(POLARSSL_PEM_PARSE_C) 00047 #include "polarssl/pem.h" 00048 #endif 00049 00050 #if defined(POLARSSL_PLATFORM_C) 00051 #include "polarssl/platform.h" 00052 #else 00053 #include <stdlib.h> 00054 #include <stdio.h> 00055 #define polarssl_free free 00056 #define polarssl_malloc malloc 00057 #define polarssl_snprintf snprintf 00058 #endif 00059 00060 #if defined(POLARSSL_FS_IO) || defined(EFIX64) || defined(EFI32) 00061 #include <stdio.h> 00062 #endif 00063 00064 /* Implementation that should never be optimized out by the compiler */ 00065 static void polarssl_zeroize( void *v, size_t n ) { 00066 volatile unsigned char *p = v; while( n-- ) *p++ = 0; 00067 } 00068 00069 /* 00070 * Version ::= INTEGER { v1(0) } 00071 */ 00072 static int x509_csr_get_version( unsigned char **p, 00073 const unsigned char *end, 00074 int *ver ) 00075 { 00076 int ret; 00077 00078 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 ) 00079 { 00080 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) 00081 { 00082 *ver = 0; 00083 return( 0 ); 00084 } 00085 00086 return( POLARSSL_ERR_X509_INVALID_VERSION + ret ); 00087 } 00088 00089 return( 0 ); 00090 } 00091 00092 /* 00093 * Parse a CSR in DER format 00094 */ 00095 int x509_csr_parse_der( x509_csr *csr, 00096 const unsigned char *buf, size_t buflen ) 00097 { 00098 int ret; 00099 size_t len; 00100 unsigned char *p, *end; 00101 x509_buf sig_params; 00102 00103 memset( &sig_params, 0, sizeof( x509_buf ) ); 00104 00105 /* 00106 * Check for valid input 00107 */ 00108 if( csr == NULL || buf == NULL ) 00109 return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); 00110 00111 x509_csr_init( csr ); 00112 00113 /* 00114 * first copy the raw DER data 00115 */ 00116 p = polarssl_malloc( len = buflen ); 00117 00118 if( p == NULL ) 00119 return( POLARSSL_ERR_X509_MALLOC_FAILED ); 00120 00121 memcpy( p, buf, buflen ); 00122 00123 csr->raw.p = p; 00124 csr->raw.len = len; 00125 end = p + len; 00126 00127 /* 00128 * CertificationRequest ::= SEQUENCE { 00129 * certificationRequestInfo CertificationRequestInfo, 00130 * signatureAlgorithm AlgorithmIdentifier, 00131 * signature BIT STRING 00132 * } 00133 */ 00134 if( ( ret = asn1_get_tag( &p, end, &len, 00135 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00136 { 00137 x509_csr_free( csr ); 00138 return( POLARSSL_ERR_X509_INVALID_FORMAT ); 00139 } 00140 00141 if( len != (size_t) ( end - p ) ) 00142 { 00143 x509_csr_free( csr ); 00144 return( POLARSSL_ERR_X509_INVALID_FORMAT + 00145 POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); 00146 } 00147 00148 /* 00149 * CertificationRequestInfo ::= SEQUENCE { 00150 */ 00151 csr->cri.p = p; 00152 00153 if( ( ret = asn1_get_tag( &p, end, &len, 00154 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00155 { 00156 x509_csr_free( csr ); 00157 return( POLARSSL_ERR_X509_INVALID_FORMAT + ret ); 00158 } 00159 00160 end = p + len; 00161 csr->cri.len = end - csr->cri.p; 00162 00163 /* 00164 * Version ::= INTEGER { v1(0) } 00165 */ 00166 if( ( ret = x509_csr_get_version( &p, end, &csr->version ) ) != 0 ) 00167 { 00168 x509_csr_free( csr ); 00169 return( ret ); 00170 } 00171 00172 csr->version++; 00173 00174 if( csr->version != 1 ) 00175 { 00176 x509_csr_free( csr ); 00177 return( POLARSSL_ERR_X509_UNKNOWN_VERSION ); 00178 } 00179 00180 /* 00181 * subject Name 00182 */ 00183 csr->subject_raw.p = p; 00184 00185 if( ( ret = asn1_get_tag( &p, end, &len, 00186 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00187 { 00188 x509_csr_free( csr ); 00189 return( POLARSSL_ERR_X509_INVALID_FORMAT + ret ); 00190 } 00191 00192 if( ( ret = x509_get_name( &p, p + len, &csr->subject ) ) != 0 ) 00193 { 00194 x509_csr_free( csr ); 00195 return( ret ); 00196 } 00197 00198 csr->subject_raw.len = p - csr->subject_raw.p; 00199 00200 /* 00201 * subjectPKInfo SubjectPublicKeyInfo 00202 */ 00203 if( ( ret = pk_parse_subpubkey( &p, end, &csr->pk ) ) != 0 ) 00204 { 00205 x509_csr_free( csr ); 00206 return( ret ); 00207 } 00208 00209 /* 00210 * attributes [0] Attributes 00211 */ 00212 if( ( ret = asn1_get_tag( &p, end, &len, 00213 ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC ) ) != 0 ) 00214 { 00215 x509_csr_free( csr ); 00216 return( POLARSSL_ERR_X509_INVALID_FORMAT + ret ); 00217 } 00218 // TODO Parse Attributes / extension requests 00219 00220 p += len; 00221 00222 end = csr->raw.p + csr->raw.len; 00223 00224 /* 00225 * signatureAlgorithm AlgorithmIdentifier, 00226 * signature BIT STRING 00227 */ 00228 if( ( ret = x509_get_alg( &p, end, &csr->sig_oid, &sig_params ) ) != 0 ) 00229 { 00230 x509_csr_free( csr ); 00231 return( ret ); 00232 } 00233 00234 if( ( ret = x509_get_sig_alg( &csr->sig_oid, &sig_params, 00235 &csr->sig_md, &csr->sig_pk, 00236 &csr->sig_opts ) ) != 0 ) 00237 { 00238 x509_csr_free( csr ); 00239 return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG ); 00240 } 00241 00242 if( ( ret = x509_get_sig( &p, end, &csr->sig ) ) != 0 ) 00243 { 00244 x509_csr_free( csr ); 00245 return( ret ); 00246 } 00247 00248 if( p != end ) 00249 { 00250 x509_csr_free( csr ); 00251 return( POLARSSL_ERR_X509_INVALID_FORMAT + 00252 POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); 00253 } 00254 00255 return( 0 ); 00256 } 00257 00258 /* 00259 * Parse a CSR, allowing for PEM or raw DER encoding 00260 */ 00261 int x509_csr_parse( x509_csr *csr, const unsigned char *buf, size_t buflen ) 00262 { 00263 int ret; 00264 #if defined(POLARSSL_PEM_PARSE_C) 00265 size_t use_len; 00266 pem_context pem; 00267 #endif 00268 00269 /* 00270 * Check for valid input 00271 */ 00272 if( csr == NULL || buf == NULL ) 00273 return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); 00274 00275 #if defined(POLARSSL_PEM_PARSE_C) 00276 pem_init( &pem ); 00277 ret = pem_read_buffer( &pem, 00278 "-----BEGIN CERTIFICATE REQUEST-----", 00279 "-----END CERTIFICATE REQUEST-----", 00280 buf, NULL, 0, &use_len ); 00281 00282 if( ret == 0 ) 00283 { 00284 /* 00285 * Was PEM encoded, parse the result 00286 */ 00287 if( ( ret = x509_csr_parse_der( csr, pem.buf , pem.buflen ) ) != 0 ) 00288 return( ret ); 00289 00290 pem_free( &pem ); 00291 return( 0 ); 00292 } 00293 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) 00294 { 00295 pem_free( &pem ); 00296 return( ret ); 00297 } 00298 else 00299 #endif /* POLARSSL_PEM_PARSE_C */ 00300 return( x509_csr_parse_der( csr, buf, buflen ) ); 00301 } 00302 00303 #if defined(POLARSSL_FS_IO) 00304 /* 00305 * Load a CSR into the structure 00306 */ 00307 int x509_csr_parse_file( x509_csr *csr, const char *path ) 00308 { 00309 int ret; 00310 size_t n; 00311 unsigned char *buf; 00312 00313 if( ( ret = pk_load_file( path, &buf, &n ) ) != 0 ) 00314 return( ret ); 00315 00316 ret = x509_csr_parse( csr, buf, n ); 00317 00318 polarssl_zeroize( buf, n + 1 ); 00319 polarssl_free( buf ); 00320 00321 return( ret ); 00322 } 00323 #endif /* POLARSSL_FS_IO */ 00324 00325 #if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \ 00326 !defined(EFI32) 00327 #include <stdarg.h> 00328 00329 #if !defined vsnprintf 00330 #define vsnprintf _vsnprintf 00331 #endif // vsnprintf 00332 00333 /* 00334 * Windows _snprintf and _vsnprintf are not compatible to linux versions. 00335 * Result value is not size of buffer needed, but -1 if no fit is possible. 00336 * 00337 * This fuction tries to 'fix' this by at least suggesting enlarging the 00338 * size by 20. 00339 */ 00340 static int compat_snprintf( char *str, size_t size, const char *format, ... ) 00341 { 00342 va_list ap; 00343 int res = -1; 00344 00345 va_start( ap, format ); 00346 00347 res = vsnprintf( str, size, format, ap ); 00348 00349 va_end( ap ); 00350 00351 // No quick fix possible 00352 if( res < 0 ) 00353 return( (int) size + 20 ); 00354 00355 return( res ); 00356 } 00357 00358 #define snprintf compat_snprintf 00359 #endif /* _MSC_VER && !snprintf && !EFIX64 && !EFI32 */ 00360 00361 #define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2 00362 00363 #define SAFE_SNPRINTF() \ 00364 { \ 00365 if( ret == -1 ) \ 00366 return( -1 ); \ 00367 \ 00368 if( (unsigned int) ret > n ) { \ 00369 p[n - 1] = '\0'; \ 00370 return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); \ 00371 } \ 00372 \ 00373 n -= (unsigned int) ret; \ 00374 p += (unsigned int) ret; \ 00375 } 00376 00377 #define BEFORE_COLON 14 00378 #define BC "14" 00379 /* 00380 * Return an informational string about the CSR. 00381 */ 00382 int x509_csr_info( char *buf, size_t size, const char *prefix, 00383 const x509_csr *csr ) 00384 { 00385 int ret; 00386 size_t n; 00387 char *p; 00388 char key_size_str[BEFORE_COLON]; 00389 00390 p = buf; 00391 n = size; 00392 00393 ret = polarssl_snprintf( p, n, "%sCSR version : %d", 00394 prefix, csr->version ); 00395 SAFE_SNPRINTF(); 00396 00397 ret = polarssl_snprintf( p, n, "\n%ssubject name : ", prefix ); 00398 SAFE_SNPRINTF(); 00399 ret = x509_dn_gets( p, n, &csr->subject ); 00400 SAFE_SNPRINTF(); 00401 00402 ret = polarssl_snprintf( p, n, "\n%ssigned using : ", prefix ); 00403 SAFE_SNPRINTF(); 00404 00405 ret = x509_sig_alg_gets( p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md, 00406 csr->sig_opts ); 00407 SAFE_SNPRINTF(); 00408 00409 if( ( ret = x509_key_size_helper( key_size_str, BEFORE_COLON, 00410 pk_get_name( &csr->pk ) ) ) != 0 ) 00411 { 00412 return( ret ); 00413 } 00414 00415 ret = polarssl_snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str, 00416 (int) pk_get_size( &csr->pk ) ); 00417 SAFE_SNPRINTF(); 00418 00419 return( (int) ( size - n ) ); 00420 } 00421 00422 /* 00423 * Initialize a CSR 00424 */ 00425 void x509_csr_init( x509_csr *csr ) 00426 { 00427 memset( csr, 0, sizeof(x509_csr) ); 00428 } 00429 00430 /* 00431 * Unallocate all CSR data 00432 */ 00433 void x509_csr_free( x509_csr *csr ) 00434 { 00435 x509_name *name_cur; 00436 x509_name *name_prv; 00437 00438 if( csr == NULL ) 00439 return; 00440 00441 pk_free( &csr->pk ); 00442 00443 #if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT) 00444 polarssl_free( csr->sig_opts ); 00445 #endif 00446 00447 name_cur = csr->subject.next; 00448 while( name_cur != NULL ) 00449 { 00450 name_prv = name_cur; 00451 name_cur = name_cur->next; 00452 polarssl_zeroize( name_prv, sizeof( x509_name ) ); 00453 polarssl_free( name_prv ); 00454 } 00455 00456 if( csr->raw.p != NULL ) 00457 { 00458 polarssl_zeroize( csr->raw.p, csr->raw.len ); 00459 polarssl_free( csr->raw.p ); 00460 } 00461 00462 polarssl_zeroize( csr, sizeof( x509_csr ) ); 00463 } 00464 00465 #endif /* POLARSSL_X509_CSR_PARSE_C */ 00466
Generated on Tue Jul 12 2022 13:50:39 by 1.7.2