Knight KE / Mbed OS Game_Master
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers x509_csr.c Source File

x509_csr.c

00001 /*
00002  *  X.509 Certificate Signing Request (CSR) parsing
00003  *
00004  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
00005  *  SPDX-License-Identifier: Apache-2.0
00006  *
00007  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
00008  *  not use this file except in compliance with the License.
00009  *  You may obtain a copy of the License at
00010  *
00011  *  http://www.apache.org/licenses/LICENSE-2.0
00012  *
00013  *  Unless required by applicable law or agreed to in writing, software
00014  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00015  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00016  *  See the License for the specific language governing permissions and
00017  *  limitations under the License.
00018  *
00019  *  This file is part of mbed TLS (https://tls.mbed.org)
00020  */
00021 /*
00022  *  The ITU-T X.509 standard defines a certificate format for PKI.
00023  *
00024  *  http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
00025  *  http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
00026  *  http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
00027  *
00028  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
00029  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
00030  */
00031 
00032 #if !defined(MBEDTLS_CONFIG_FILE)
00033 #include "mbedtls/config.h"
00034 #else
00035 #include MBEDTLS_CONFIG_FILE
00036 #endif
00037 
00038 #if defined(MBEDTLS_X509_CSR_PARSE_C)
00039 
00040 #include "mbedtls/x509_csr.h"
00041 #include "mbedtls/oid.h"
00042 #include "mbedtls/platform_util.h"
00043 
00044 #include <string.h>
00045 
00046 #if defined(MBEDTLS_PEM_PARSE_C)
00047 #include "mbedtls/pem.h"
00048 #endif
00049 
00050 #if defined(MBEDTLS_PLATFORM_C)
00051 #include "mbedtls/platform.h"
00052 #else
00053 #include <stdlib.h>
00054 #include <stdio.h>
00055 #define mbedtls_free       free
00056 #define mbedtls_calloc    calloc
00057 #define mbedtls_snprintf   snprintf
00058 #endif
00059 
00060 #if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32)
00061 #include <stdio.h>
00062 #endif
00063 
00064 /*
00065  *  Version  ::=  INTEGER  {  v1(0)  }
00066  */
00067 static int x509_csr_get_version( unsigned char **p,
00068                              const unsigned char *end,
00069                              int *ver )
00070 {
00071     int ret;
00072 
00073     if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
00074     {
00075         if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
00076         {
00077             *ver = 0;
00078             return( 0 );
00079         }
00080 
00081         return( MBEDTLS_ERR_X509_INVALID_VERSION + ret );
00082     }
00083 
00084     return( 0 );
00085 }
00086 
00087 /*
00088  * Parse a CSR in DER format
00089  */
00090 int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
00091                         const unsigned char *buf, size_t buflen )
00092 {
00093     int ret;
00094     size_t len;
00095     unsigned char *p, *end;
00096     mbedtls_x509_buf sig_params;
00097 
00098     memset( &sig_params, 0, sizeof( mbedtls_x509_buf ) );
00099 
00100     /*
00101      * Check for valid input
00102      */
00103     if( csr == NULL || buf == NULL || buflen == 0 )
00104         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
00105 
00106     mbedtls_x509_csr_init( csr );
00107 
00108     /*
00109      * first copy the raw DER data
00110      */
00111     p = mbedtls_calloc( 1, len = buflen );
00112 
00113     if( p == NULL )
00114         return( MBEDTLS_ERR_X509_ALLOC_FAILED );
00115 
00116     memcpy( p, buf, buflen );
00117 
00118     csr->raw.p = p;
00119     csr->raw.len = len;
00120     end = p + len;
00121 
00122     /*
00123      *  CertificationRequest ::= SEQUENCE {
00124      *       certificationRequestInfo CertificationRequestInfo,
00125      *       signatureAlgorithm AlgorithmIdentifier,
00126      *       signature          BIT STRING
00127      *  }
00128      */
00129     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
00130             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
00131     {
00132         mbedtls_x509_csr_free( csr );
00133         return( MBEDTLS_ERR_X509_INVALID_FORMAT );
00134     }
00135 
00136     if( len != (size_t) ( end - p ) )
00137     {
00138         mbedtls_x509_csr_free( csr );
00139         return( MBEDTLS_ERR_X509_INVALID_FORMAT +
00140                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
00141     }
00142 
00143     /*
00144      *  CertificationRequestInfo ::= SEQUENCE {
00145      */
00146     csr->cri.p = p;
00147 
00148     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
00149             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
00150     {
00151         mbedtls_x509_csr_free( csr );
00152         return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
00153     }
00154 
00155     end = p + len;
00156     csr->cri.len = end - csr->cri.p;
00157 
00158     /*
00159      *  Version  ::=  INTEGER {  v1(0) }
00160      */
00161     if( ( ret = x509_csr_get_version( &p, end, &csr->version ) ) != 0 )
00162     {
00163         mbedtls_x509_csr_free( csr );
00164         return( ret );
00165     }
00166 
00167     if( csr->version != 0 )
00168     {
00169         mbedtls_x509_csr_free( csr );
00170         return( MBEDTLS_ERR_X509_UNKNOWN_VERSION );
00171     }
00172 
00173     csr->version++;
00174 
00175     /*
00176      *  subject               Name
00177      */
00178     csr->subject_raw.p = p;
00179 
00180     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
00181             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
00182     {
00183         mbedtls_x509_csr_free( csr );
00184         return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
00185     }
00186 
00187     if( ( ret = mbedtls_x509_get_name( &p, p + len, &csr->subject ) ) != 0 )
00188     {
00189         mbedtls_x509_csr_free( csr );
00190         return( ret );
00191     }
00192 
00193     csr->subject_raw.len = p - csr->subject_raw.p;
00194 
00195     /*
00196      *  subjectPKInfo SubjectPublicKeyInfo
00197      */
00198     if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &csr->pk ) ) != 0 )
00199     {
00200         mbedtls_x509_csr_free( csr );
00201         return( ret );
00202     }
00203 
00204     /*
00205      *  attributes    [0] Attributes
00206      *
00207      *  The list of possible attributes is open-ended, though RFC 2985
00208      *  (PKCS#9) defines a few in section 5.4. We currently don't support any,
00209      *  so we just ignore them. This is a safe thing to do as the worst thing
00210      *  that could happen is that we issue a certificate that does not match
00211      *  the requester's expectations - this cannot cause a violation of our
00212      *  signature policies.
00213      */
00214     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
00215             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 )
00216     {
00217         mbedtls_x509_csr_free( csr );
00218         return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
00219     }
00220 
00221     p += len;
00222 
00223     end = csr->raw.p + csr->raw.len;
00224 
00225     /*
00226      *  signatureAlgorithm   AlgorithmIdentifier,
00227      *  signature            BIT STRING
00228      */
00229     if( ( ret = mbedtls_x509_get_alg( &p, end, &csr->sig_oid, &sig_params ) ) != 0 )
00230     {
00231         mbedtls_x509_csr_free( csr );
00232         return( ret );
00233     }
00234 
00235     if( ( ret = mbedtls_x509_get_sig_alg( &csr->sig_oid, &sig_params,
00236                                   &csr->sig_md, &csr->sig_pk,
00237                                   &csr->sig_opts ) ) != 0 )
00238     {
00239         mbedtls_x509_csr_free( csr );
00240         return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG );
00241     }
00242 
00243     if( ( ret = mbedtls_x509_get_sig( &p, end, &csr->sig ) ) != 0 )
00244     {
00245         mbedtls_x509_csr_free( csr );
00246         return( ret );
00247     }
00248 
00249     if( p != end )
00250     {
00251         mbedtls_x509_csr_free( csr );
00252         return( MBEDTLS_ERR_X509_INVALID_FORMAT +
00253                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
00254     }
00255 
00256     return( 0 );
00257 }
00258 
00259 /*
00260  * Parse a CSR, allowing for PEM or raw DER encoding
00261  */
00262 int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen )
00263 {
00264 #if defined(MBEDTLS_PEM_PARSE_C)
00265     int ret;
00266     size_t use_len;
00267     mbedtls_pem_context pem;
00268 #endif
00269 
00270     /*
00271      * Check for valid input
00272      */
00273     if( csr == NULL || buf == NULL || buflen == 0 )
00274         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
00275 
00276 #if defined(MBEDTLS_PEM_PARSE_C)
00277     mbedtls_pem_init( &pem );
00278 
00279     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
00280     if( buf[buflen - 1] != '\0' )
00281         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
00282     else
00283         ret = mbedtls_pem_read_buffer( &pem,
00284                                "-----BEGIN CERTIFICATE REQUEST-----",
00285                                "-----END CERTIFICATE REQUEST-----",
00286                                buf, NULL, 0, &use_len );
00287 
00288     if( ret == 0 )
00289     {
00290         /*
00291          * Was PEM encoded, parse the result
00292          */
00293         if( ( ret = mbedtls_x509_csr_parse_der( csr, pem.buf , pem.buflen  ) ) != 0 )
00294             return( ret );
00295 
00296         mbedtls_pem_free( &pem );
00297         return( 0 );
00298     }
00299     else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
00300     {
00301         mbedtls_pem_free( &pem );
00302         return( ret );
00303     }
00304     else
00305 #endif /* MBEDTLS_PEM_PARSE_C */
00306     return( mbedtls_x509_csr_parse_der( csr, buf, buflen ) );
00307 }
00308 
00309 #if defined(MBEDTLS_FS_IO)
00310 /*
00311  * Load a CSR into the structure
00312  */
00313 int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path )
00314 {
00315     int ret;
00316     size_t n;
00317     unsigned char *buf;
00318 
00319     if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
00320         return( ret );
00321 
00322     ret = mbedtls_x509_csr_parse( csr, buf, n );
00323 
00324     mbedtls_platform_zeroize( buf, n );
00325     mbedtls_free( buf );
00326 
00327     return( ret );
00328 }
00329 #endif /* MBEDTLS_FS_IO */
00330 
00331 #define BEFORE_COLON    14
00332 #define BC              "14"
00333 /*
00334  * Return an informational string about the CSR.
00335  */
00336 int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix,
00337                    const mbedtls_x509_csr *csr )
00338 {
00339     int ret;
00340     size_t n;
00341     char *p;
00342     char key_size_str[BEFORE_COLON];
00343 
00344     p = buf;
00345     n = size;
00346 
00347     ret = mbedtls_snprintf( p, n, "%sCSR version   : %d",
00348                                prefix, csr->version );
00349     MBEDTLS_X509_SAFE_SNPRINTF;
00350 
00351     ret = mbedtls_snprintf( p, n, "\n%ssubject name  : ", prefix );
00352     MBEDTLS_X509_SAFE_SNPRINTF;
00353     ret = mbedtls_x509_dn_gets( p, n, &csr->subject );
00354     MBEDTLS_X509_SAFE_SNPRINTF;
00355 
00356     ret = mbedtls_snprintf( p, n, "\n%ssigned using  : ", prefix );
00357     MBEDTLS_X509_SAFE_SNPRINTF;
00358 
00359     ret = mbedtls_x509_sig_alg_gets( p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md,
00360                              csr->sig_opts );
00361     MBEDTLS_X509_SAFE_SNPRINTF;
00362 
00363     if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON,
00364                                       mbedtls_pk_get_name( &csr->pk ) ) ) != 0 )
00365     {
00366         return( ret );
00367     }
00368 
00369     ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str,
00370                           (int) mbedtls_pk_get_bitlen( &csr->pk ) );
00371     MBEDTLS_X509_SAFE_SNPRINTF;
00372 
00373     return( (int) ( size - n ) );
00374 }
00375 
00376 /*
00377  * Initialize a CSR
00378  */
00379 void mbedtls_x509_csr_init( mbedtls_x509_csr *csr )
00380 {
00381     memset( csr, 0, sizeof(mbedtls_x509_csr) );
00382 }
00383 
00384 /*
00385  * Unallocate all CSR data
00386  */
00387 void mbedtls_x509_csr_free( mbedtls_x509_csr *csr )
00388 {
00389     mbedtls_x509_name *name_cur;
00390     mbedtls_x509_name *name_prv;
00391 
00392     if( csr == NULL )
00393         return;
00394 
00395     mbedtls_pk_free( &csr->pk );
00396 
00397 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
00398     mbedtls_free( csr->sig_opts );
00399 #endif
00400 
00401     name_cur = csr->subject.next;
00402     while( name_cur != NULL )
00403     {
00404         name_prv = name_cur;
00405         name_cur = name_cur->next;
00406         mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
00407         mbedtls_free( name_prv );
00408     }
00409 
00410     if( csr->raw.p != NULL )
00411     {
00412         mbedtls_platform_zeroize( csr->raw.p, csr->raw.len );
00413         mbedtls_free( csr->raw.p );
00414     }
00415 
00416     mbedtls_platform_zeroize( csr, sizeof( mbedtls_x509_csr ) );
00417 }
00418 
00419 #endif /* MBEDTLS_X509_CSR_PARSE_C */