Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers x509write_csr.c Source File

x509write_csr.c

00001 /*
00002  *  X.509 Certificate Signing Request writing
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  * References:
00023  * - CSRs: PKCS#10 v1.7 aka RFC 2986
00024  * - attributes: PKCS#9 v2.0 aka RFC 2985
00025  */
00026 
00027 #if !defined(MBEDTLS_CONFIG_FILE)
00028 #include "mbedtls/config.h"
00029 #else
00030 #include MBEDTLS_CONFIG_FILE
00031 #endif
00032 
00033 #if defined(MBEDTLS_X509_CSR_WRITE_C)
00034 
00035 #include "mbedtls/x509_csr.h"
00036 #include "mbedtls/oid.h"
00037 #include "mbedtls/asn1write.h"
00038 #include "mbedtls/platform_util.h"
00039 
00040 #if defined(MBEDTLS_USE_PSA_CRYPTO)
00041 #include "psa/crypto.h"
00042 #include "mbedtls/psa_util.h"
00043 #endif
00044 
00045 #include <string.h>
00046 #include <stdlib.h>
00047 
00048 #if defined(MBEDTLS_PEM_WRITE_C)
00049 #include "mbedtls/pem.h"
00050 #endif
00051 
00052 /*
00053  * For the currently used signature algorithms the buffer to store any signature
00054  * must be at least of size MAX(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)
00055  */
00056 #if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE
00057 #define SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN
00058 #else
00059 #define SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE
00060 #endif
00061 
00062 void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx )
00063 {
00064     memset( ctx, 0, sizeof( mbedtls_x509write_csr ) );
00065 }
00066 
00067 void mbedtls_x509write_csr_free( mbedtls_x509write_csr *ctx )
00068 {
00069     mbedtls_asn1_free_named_data_list( &ctx->subject );
00070     mbedtls_asn1_free_named_data_list( &ctx->extensions );
00071 
00072     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_x509write_csr ) );
00073 }
00074 
00075 void mbedtls_x509write_csr_set_md_alg( mbedtls_x509write_csr *ctx, mbedtls_md_type_t md_alg )
00076 {
00077     ctx->md_alg = md_alg;
00078 }
00079 
00080 void mbedtls_x509write_csr_set_key( mbedtls_x509write_csr *ctx, mbedtls_pk_context *key )
00081 {
00082     ctx->key = key;
00083 }
00084 
00085 int mbedtls_x509write_csr_set_subject_name( mbedtls_x509write_csr *ctx,
00086                                     const char *subject_name )
00087 {
00088     return mbedtls_x509_string_to_names( &ctx->subject, subject_name );
00089 }
00090 
00091 int mbedtls_x509write_csr_set_extension( mbedtls_x509write_csr *ctx,
00092                                  const char *oid, size_t oid_len,
00093                                  const unsigned char *val, size_t val_len )
00094 {
00095     return mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len,
00096                                0, val, val_len );
00097 }
00098 
00099 int mbedtls_x509write_csr_set_key_usage( mbedtls_x509write_csr *ctx, unsigned char key_usage )
00100 {
00101     unsigned char buf[4];
00102     unsigned char *c;
00103     int ret;
00104 
00105     c = buf + 4;
00106 
00107     ret = mbedtls_asn1_write_named_bitstring( &c, buf, &key_usage, 8 );
00108     if( ret < 3 || ret > 4 )
00109         return( ret );
00110 
00111     ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_KEY_USAGE,
00112                                        MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ),
00113                                        c, (size_t)ret );
00114     if( ret != 0 )
00115         return( ret );
00116 
00117     return( 0 );
00118 }
00119 
00120 int mbedtls_x509write_csr_set_ns_cert_type( mbedtls_x509write_csr *ctx,
00121                                     unsigned char ns_cert_type )
00122 {
00123     unsigned char buf[4];
00124     unsigned char *c;
00125     int ret;
00126 
00127     c = buf + 4;
00128 
00129     ret = mbedtls_asn1_write_named_bitstring( &c, buf, &ns_cert_type, 8 );
00130     if( ret < 3 || ret > 4 )
00131         return( ret );
00132 
00133     ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE,
00134                                        MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ),
00135                                        c, (size_t)ret );
00136     if( ret != 0 )
00137         return( ret );
00138 
00139     return( 0 );
00140 }
00141 
00142 int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
00143                        int (*f_rng)(void *, unsigned char *, size_t),
00144                        void *p_rng )
00145 {
00146     int ret;
00147     const char *sig_oid;
00148     size_t sig_oid_len = 0;
00149     unsigned char *c, *c2;
00150     unsigned char hash[64];
00151     unsigned char sig[SIGNATURE_MAX_SIZE];
00152     unsigned char tmp_buf[2048];
00153     size_t pub_len = 0, sig_and_oid_len = 0, sig_len;
00154     size_t len = 0;
00155     mbedtls_pk_type_t pk_alg;
00156 #if defined(MBEDTLS_USE_PSA_CRYPTO)
00157     psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT;
00158     size_t hash_len;
00159     psa_algorithm_t hash_alg = mbedtls_psa_translate_md( ctx->md_alg );
00160 #endif /* MBEDTLS_USE_PSA_CRYPTO */
00161     /*
00162      * Prepare data to be signed in tmp_buf
00163      */
00164     c = tmp_buf + sizeof( tmp_buf );
00165 
00166     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, tmp_buf, ctx->extensions ) );
00167 
00168     if( len )
00169     {
00170         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
00171         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
00172                                                         MBEDTLS_ASN1_SEQUENCE ) );
00173 
00174         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
00175         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
00176                                                         MBEDTLS_ASN1_SET ) );
00177 
00178         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( &c, tmp_buf, MBEDTLS_OID_PKCS9_CSR_EXT_REQ,
00179                                           MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS9_CSR_EXT_REQ ) ) );
00180 
00181         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
00182         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
00183                                                         MBEDTLS_ASN1_SEQUENCE ) );
00184     }
00185 
00186     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
00187     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
00188                                                     MBEDTLS_ASN1_CONTEXT_SPECIFIC ) );
00189 
00190     MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->key,
00191                                                 tmp_buf, c - tmp_buf ) );
00192     c -= pub_len;
00193     len += pub_len;
00194 
00195     /*
00196      *  Subject  ::=  Name
00197      */
00198     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->subject ) );
00199 
00200     /*
00201      *  Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
00202      */
00203     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, tmp_buf, 0 ) );
00204 
00205     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
00206     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
00207                                                     MBEDTLS_ASN1_SEQUENCE ) );
00208 
00209     /*
00210      * Prepare signature
00211      * Note: hash errors can happen only after an internal error
00212      */
00213 #if defined(MBEDTLS_USE_PSA_CRYPTO)
00214     if( psa_hash_setup( &hash_operation, hash_alg ) != PSA_SUCCESS )
00215         return( MBEDTLS_ERR_X509_FATAL_ERROR );
00216 
00217     if( psa_hash_update( &hash_operation, c, len ) != PSA_SUCCESS )
00218         return( MBEDTLS_ERR_X509_FATAL_ERROR );
00219 
00220     if( psa_hash_finish( &hash_operation, hash, sizeof( hash ), &hash_len )
00221         != PSA_SUCCESS )
00222     {
00223         return( MBEDTLS_ERR_X509_FATAL_ERROR );
00224     }
00225 #else /* MBEDTLS_USE_PSA_CRYPTO */
00226     mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash );
00227 #endif
00228     if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len,
00229                                  f_rng, p_rng ) ) != 0 )
00230     {
00231         return( ret );
00232     }
00233 
00234     if( mbedtls_pk_can_do( ctx->key, MBEDTLS_PK_RSA ) )
00235         pk_alg = MBEDTLS_PK_RSA;
00236     else if( mbedtls_pk_can_do( ctx->key, MBEDTLS_PK_ECDSA ) )
00237         pk_alg = MBEDTLS_PK_ECDSA;
00238     else
00239         return( MBEDTLS_ERR_X509_INVALID_ALG );
00240 
00241     if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
00242                                                 &sig_oid, &sig_oid_len ) ) != 0 )
00243     {
00244         return( ret );
00245     }
00246 
00247     /*
00248      * Write data to output buffer
00249      */
00250     c2 = buf + size;
00251     MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf,
00252                                         sig_oid, sig_oid_len, sig, sig_len ) );
00253 
00254     if( len > (size_t)( c2 - buf ) )
00255         return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
00256 
00257     c2 -= len;
00258     memcpy( c2, c, len );
00259 
00260     len += sig_and_oid_len;
00261     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) );
00262     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c2, buf, MBEDTLS_ASN1_CONSTRUCTED |
00263                                                  MBEDTLS_ASN1_SEQUENCE ) );
00264 
00265     return( (int) len );
00266 }
00267 
00268 #define PEM_BEGIN_CSR           "-----BEGIN CERTIFICATE REQUEST-----\n"
00269 #define PEM_END_CSR             "-----END CERTIFICATE REQUEST-----\n"
00270 
00271 #if defined(MBEDTLS_PEM_WRITE_C)
00272 int mbedtls_x509write_csr_pem( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
00273                        int (*f_rng)(void *, unsigned char *, size_t),
00274                        void *p_rng )
00275 {
00276     int ret;
00277     unsigned char output_buf[4096];
00278     size_t olen = 0;
00279 
00280     if( ( ret = mbedtls_x509write_csr_der( ctx, output_buf, sizeof(output_buf),
00281                                    f_rng, p_rng ) ) < 0 )
00282     {
00283         return( ret );
00284     }
00285 
00286     if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CSR, PEM_END_CSR,
00287                                   output_buf + sizeof(output_buf) - ret,
00288                                   ret, buf, size, &olen ) ) != 0 )
00289     {
00290         return( ret );
00291     }
00292 
00293     return( 0 );
00294 }
00295 #endif /* MBEDTLS_PEM_WRITE_C */
00296 
00297 #endif /* MBEDTLS_X509_CSR_WRITE_C */