takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

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     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
00278     if( buf[buflen - 1] == '\0' )
00279     {
00280         mbedtls_pem_init( &pem );
00281         ret = mbedtls_pem_read_buffer( &pem,
00282                                "-----BEGIN CERTIFICATE REQUEST-----",
00283                                "-----END CERTIFICATE REQUEST-----",
00284                                buf, NULL, 0, &use_len );
00285 
00286         if( ret == 0 )
00287             /*
00288              * Was PEM encoded, parse the result
00289              */
00290             ret = mbedtls_x509_csr_parse_der( csr, pem.buf , pem.buflen  );
00291 
00292         mbedtls_pem_free( &pem );
00293         if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
00294             return( ret );
00295     }
00296 #endif /* MBEDTLS_PEM_PARSE_C */
00297     return( mbedtls_x509_csr_parse_der( csr, buf, buflen ) );
00298 }
00299 
00300 #if defined(MBEDTLS_FS_IO)
00301 /*
00302  * Load a CSR into the structure
00303  */
00304 int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path )
00305 {
00306     int ret;
00307     size_t n;
00308     unsigned char *buf;
00309 
00310     if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
00311         return( ret );
00312 
00313     ret = mbedtls_x509_csr_parse( csr, buf, n );
00314 
00315     mbedtls_platform_zeroize( buf, n );
00316     mbedtls_free( buf );
00317 
00318     return( ret );
00319 }
00320 #endif /* MBEDTLS_FS_IO */
00321 
00322 #define BEFORE_COLON    14
00323 #define BC              "14"
00324 /*
00325  * Return an informational string about the CSR.
00326  */
00327 int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix,
00328                    const mbedtls_x509_csr *csr )
00329 {
00330     int ret;
00331     size_t n;
00332     char *p;
00333     char key_size_str[BEFORE_COLON];
00334 
00335     p = buf;
00336     n = size;
00337 
00338     ret = mbedtls_snprintf( p, n, "%sCSR version   : %d",
00339                                prefix, csr->version );
00340     MBEDTLS_X509_SAFE_SNPRINTF;
00341 
00342     ret = mbedtls_snprintf( p, n, "\n%ssubject name  : ", prefix );
00343     MBEDTLS_X509_SAFE_SNPRINTF;
00344     ret = mbedtls_x509_dn_gets( p, n, &csr->subject );
00345     MBEDTLS_X509_SAFE_SNPRINTF;
00346 
00347     ret = mbedtls_snprintf( p, n, "\n%ssigned using  : ", prefix );
00348     MBEDTLS_X509_SAFE_SNPRINTF;
00349 
00350     ret = mbedtls_x509_sig_alg_gets( p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md,
00351                              csr->sig_opts );
00352     MBEDTLS_X509_SAFE_SNPRINTF;
00353 
00354     if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON,
00355                                       mbedtls_pk_get_name( &csr->pk ) ) ) != 0 )
00356     {
00357         return( ret );
00358     }
00359 
00360     ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str,
00361                           (int) mbedtls_pk_get_bitlen( &csr->pk ) );
00362     MBEDTLS_X509_SAFE_SNPRINTF;
00363 
00364     return( (int) ( size - n ) );
00365 }
00366 
00367 /*
00368  * Initialize a CSR
00369  */
00370 void mbedtls_x509_csr_init( mbedtls_x509_csr *csr )
00371 {
00372     memset( csr, 0, sizeof(mbedtls_x509_csr) );
00373 }
00374 
00375 /*
00376  * Unallocate all CSR data
00377  */
00378 void mbedtls_x509_csr_free( mbedtls_x509_csr *csr )
00379 {
00380     mbedtls_x509_name *name_cur;
00381     mbedtls_x509_name *name_prv;
00382 
00383     if( csr == NULL )
00384         return;
00385 
00386     mbedtls_pk_free( &csr->pk );
00387 
00388 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
00389     mbedtls_free( csr->sig_opts );
00390 #endif
00391 
00392     name_cur = csr->subject.next;
00393     while( name_cur != NULL )
00394     {
00395         name_prv = name_cur;
00396         name_cur = name_cur->next;
00397         mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
00398         mbedtls_free( name_prv );
00399     }
00400 
00401     if( csr->raw.p != NULL )
00402     {
00403         mbedtls_platform_zeroize( csr->raw.p, csr->raw.len );
00404         mbedtls_free( csr->raw.p );
00405     }
00406 
00407     mbedtls_platform_zeroize( csr, sizeof( mbedtls_x509_csr ) );
00408 }
00409 
00410 #endif /* MBEDTLS_X509_CSR_PARSE_C */