Knight KE / Mbed OS Game_Master
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 #include <string.h>
00041 #include <stdlib.h>
00042 
00043 #if defined(MBEDTLS_PEM_WRITE_C)
00044 #include "mbedtls/pem.h"
00045 #endif
00046 
00047 void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx )
00048 {
00049     memset( ctx, 0, sizeof( mbedtls_x509write_csr ) );
00050 }
00051 
00052 void mbedtls_x509write_csr_free( mbedtls_x509write_csr *ctx )
00053 {
00054     mbedtls_asn1_free_named_data_list( &ctx->subject );
00055     mbedtls_asn1_free_named_data_list( &ctx->extensions );
00056 
00057     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_x509write_csr ) );
00058 }
00059 
00060 void mbedtls_x509write_csr_set_md_alg( mbedtls_x509write_csr *ctx, mbedtls_md_type_t md_alg )
00061 {
00062     ctx->md_alg = md_alg;
00063 }
00064 
00065 void mbedtls_x509write_csr_set_key( mbedtls_x509write_csr *ctx, mbedtls_pk_context *key )
00066 {
00067     ctx->key = key;
00068 }
00069 
00070 int mbedtls_x509write_csr_set_subject_name( mbedtls_x509write_csr *ctx,
00071                                     const char *subject_name )
00072 {
00073     return mbedtls_x509_string_to_names( &ctx->subject, subject_name );
00074 }
00075 
00076 int mbedtls_x509write_csr_set_extension( mbedtls_x509write_csr *ctx,
00077                                  const char *oid, size_t oid_len,
00078                                  const unsigned char *val, size_t val_len )
00079 {
00080     return mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len,
00081                                0, val, val_len );
00082 }
00083 
00084 int mbedtls_x509write_csr_set_key_usage( mbedtls_x509write_csr *ctx, unsigned char key_usage )
00085 {
00086     unsigned char buf[4];
00087     unsigned char *c;
00088     int ret;
00089 
00090     c = buf + 4;
00091 
00092     if( ( ret = mbedtls_asn1_write_bitstring( &c, buf, &key_usage, 7 ) ) != 4 )
00093         return( ret );
00094 
00095     ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_KEY_USAGE,
00096                                        MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ),
00097                                        buf, 4 );
00098     if( ret != 0 )
00099         return( ret );
00100 
00101     return( 0 );
00102 }
00103 
00104 int mbedtls_x509write_csr_set_ns_cert_type( mbedtls_x509write_csr *ctx,
00105                                     unsigned char ns_cert_type )
00106 {
00107     unsigned char buf[4];
00108     unsigned char *c;
00109     int ret;
00110 
00111     c = buf + 4;
00112 
00113     if( ( ret = mbedtls_asn1_write_bitstring( &c, buf, &ns_cert_type, 8 ) ) != 4 )
00114         return( ret );
00115 
00116     ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE,
00117                                        MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ),
00118                                        buf, 4 );
00119     if( ret != 0 )
00120         return( ret );
00121 
00122     return( 0 );
00123 }
00124 
00125 int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
00126                        int (*f_rng)(void *, unsigned char *, size_t),
00127                        void *p_rng )
00128 {
00129     int ret;
00130     const char *sig_oid;
00131     size_t sig_oid_len = 0;
00132     unsigned char *c, *c2;
00133     unsigned char hash[64];
00134     unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
00135     unsigned char tmp_buf[2048];
00136     size_t pub_len = 0, sig_and_oid_len = 0, sig_len;
00137     size_t len = 0;
00138     mbedtls_pk_type_t pk_alg;
00139 
00140     /*
00141      * Prepare data to be signed in tmp_buf
00142      */
00143     c = tmp_buf + sizeof( tmp_buf );
00144 
00145     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, tmp_buf, ctx->extensions ) );
00146 
00147     if( len )
00148     {
00149         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
00150         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
00151                                                         MBEDTLS_ASN1_SEQUENCE ) );
00152 
00153         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
00154         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
00155                                                         MBEDTLS_ASN1_SET ) );
00156 
00157         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( &c, tmp_buf, MBEDTLS_OID_PKCS9_CSR_EXT_REQ,
00158                                           MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS9_CSR_EXT_REQ ) ) );
00159 
00160         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
00161         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
00162                                                         MBEDTLS_ASN1_SEQUENCE ) );
00163     }
00164 
00165     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
00166     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
00167                                                     MBEDTLS_ASN1_CONTEXT_SPECIFIC ) );
00168 
00169     MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->key,
00170                                                 tmp_buf, c - tmp_buf ) );
00171     c -= pub_len;
00172     len += pub_len;
00173 
00174     /*
00175      *  Subject  ::=  Name
00176      */
00177     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->subject ) );
00178 
00179     /*
00180      *  Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
00181      */
00182     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, tmp_buf, 0 ) );
00183 
00184     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
00185     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
00186                                                     MBEDTLS_ASN1_SEQUENCE ) );
00187 
00188     /*
00189      * Prepare signature
00190      */
00191     mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash );
00192 
00193     if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len,
00194                                  f_rng, p_rng ) ) != 0 )
00195     {
00196         return( ret );
00197     }
00198 
00199     if( mbedtls_pk_can_do( ctx->key, MBEDTLS_PK_RSA ) )
00200         pk_alg = MBEDTLS_PK_RSA;
00201     else if( mbedtls_pk_can_do( ctx->key, MBEDTLS_PK_ECDSA ) )
00202         pk_alg = MBEDTLS_PK_ECDSA;
00203     else
00204         return( MBEDTLS_ERR_X509_INVALID_ALG );
00205 
00206     if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
00207                                                 &sig_oid, &sig_oid_len ) ) != 0 )
00208     {
00209         return( ret );
00210     }
00211 
00212     /*
00213      * Write data to output buffer
00214      */
00215     c2 = buf + size;
00216     MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf,
00217                                         sig_oid, sig_oid_len, sig, sig_len ) );
00218 
00219     if( len > (size_t)( c2 - buf ) )
00220         return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
00221 
00222     c2 -= len;
00223     memcpy( c2, c, len );
00224 
00225     len += sig_and_oid_len;
00226     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) );
00227     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c2, buf, MBEDTLS_ASN1_CONSTRUCTED |
00228                                                  MBEDTLS_ASN1_SEQUENCE ) );
00229 
00230     return( (int) len );
00231 }
00232 
00233 #define PEM_BEGIN_CSR           "-----BEGIN CERTIFICATE REQUEST-----\n"
00234 #define PEM_END_CSR             "-----END CERTIFICATE REQUEST-----\n"
00235 
00236 #if defined(MBEDTLS_PEM_WRITE_C)
00237 int mbedtls_x509write_csr_pem( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
00238                        int (*f_rng)(void *, unsigned char *, size_t),
00239                        void *p_rng )
00240 {
00241     int ret;
00242     unsigned char output_buf[4096];
00243     size_t olen = 0;
00244 
00245     if( ( ret = mbedtls_x509write_csr_der( ctx, output_buf, sizeof(output_buf),
00246                                    f_rng, p_rng ) ) < 0 )
00247     {
00248         return( ret );
00249     }
00250 
00251     if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CSR, PEM_END_CSR,
00252                                   output_buf + sizeof(output_buf) - ret,
00253                                   ret, buf, size, &olen ) ) != 0 )
00254     {
00255         return( ret );
00256     }
00257 
00258     return( 0 );
00259 }
00260 #endif /* MBEDTLS_PEM_WRITE_C */
00261 
00262 #endif /* MBEDTLS_X509_CSR_WRITE_C */