quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

x509_csr.c (19804B)


      1 /*
      2  *  X.509 Certificate Signing Request (CSR) parsing
      3  *
      4  *  Copyright The Mbed TLS Contributors
      5  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
      6  */
      7 /*
      8  *  The ITU-T X.509 standard defines a certificate format for PKI.
      9  *
     10  *  http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
     11  *  http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
     12  *  http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
     13  *
     14  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
     15  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
     16  */
     17 
     18 #include "common.h"
     19 
     20 #if defined(MBEDTLS_X509_CSR_PARSE_C)
     21 
     22 #include "mbedtls/x509_csr.h"
     23 #include "x509_internal.h"
     24 #include "mbedtls/error.h"
     25 #include "mbedtls/oid.h"
     26 #include "mbedtls/platform_util.h"
     27 
     28 #include <string.h>
     29 
     30 #if defined(MBEDTLS_PEM_PARSE_C)
     31 #include "mbedtls/pem.h"
     32 #endif
     33 
     34 #include "mbedtls/platform.h"
     35 
     36 #if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32)
     37 #include <stdio.h>
     38 #endif
     39 
     40 /*
     41  *  Version  ::=  INTEGER  {  v1(0)  }
     42  */
     43 static int x509_csr_get_version(unsigned char **p,
     44                                 const unsigned char *end,
     45                                 int *ver)
     46 {
     47     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     48 
     49     if ((ret = mbedtls_asn1_get_int(p, end, ver)) != 0) {
     50         if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
     51             *ver = 0;
     52             return 0;
     53         }
     54 
     55         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_VERSION, ret);
     56     }
     57 
     58     return 0;
     59 }
     60 
     61 /*
     62  * Parse CSR extension requests in DER format
     63  */
     64 static int x509_csr_parse_extensions(mbedtls_x509_csr *csr,
     65                                      unsigned char **p, const unsigned char *end,
     66                                      mbedtls_x509_csr_ext_cb_t cb,
     67                                      void *p_ctx)
     68 {
     69     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     70     size_t len;
     71     unsigned char *end_ext_data, *end_ext_octet;
     72 
     73     while (*p < end) {
     74         mbedtls_x509_buf extn_oid = { 0, 0, NULL };
     75         int is_critical = 0; /* DEFAULT FALSE */
     76         int ext_type = 0;
     77 
     78         /* Read sequence tag */
     79         if ((ret = mbedtls_asn1_get_tag(p, end, &len,
     80                                         MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
     81             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
     82         }
     83 
     84         end_ext_data = *p + len;
     85 
     86         /* Get extension ID */
     87         if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &extn_oid.len,
     88                                         MBEDTLS_ASN1_OID)) != 0) {
     89             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
     90         }
     91 
     92         extn_oid.tag = MBEDTLS_ASN1_OID;
     93         extn_oid.p = *p;
     94         *p += extn_oid.len;
     95 
     96         /* Get optional critical */
     97         if ((ret = mbedtls_asn1_get_bool(p, end_ext_data, &is_critical)) != 0 &&
     98             (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) {
     99             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
    100         }
    101 
    102         /* Data should be octet string type */
    103         if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &len,
    104                                         MBEDTLS_ASN1_OCTET_STRING)) != 0) {
    105             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
    106         }
    107 
    108         end_ext_octet = *p + len;
    109 
    110         if (end_ext_octet != end_ext_data) {
    111             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
    112                                      MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
    113         }
    114 
    115         /*
    116          * Detect supported extensions and skip unsupported extensions
    117          */
    118         ret = mbedtls_oid_get_x509_ext_type(&extn_oid, &ext_type);
    119 
    120         if (ret != 0) {
    121             /* Give the callback (if any) a chance to handle the extension */
    122             if (cb != NULL) {
    123                 ret = cb(p_ctx, csr, &extn_oid, is_critical, *p, end_ext_octet);
    124                 if (ret != 0 && is_critical) {
    125                     return ret;
    126                 }
    127                 *p = end_ext_octet;
    128                 continue;
    129             }
    130 
    131             /* No parser found, skip extension */
    132             *p = end_ext_octet;
    133 
    134             if (is_critical) {
    135                 /* Data is marked as critical: fail */
    136                 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
    137                                          MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
    138             }
    139             continue;
    140         }
    141 
    142         /* Forbid repeated extensions */
    143         if ((csr->ext_types & ext_type) != 0) {
    144             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
    145                                      MBEDTLS_ERR_ASN1_INVALID_DATA);
    146         }
    147 
    148         csr->ext_types |= ext_type;
    149 
    150         switch (ext_type) {
    151             case MBEDTLS_X509_EXT_KEY_USAGE:
    152                 /* Parse key usage */
    153                 if ((ret = mbedtls_x509_get_key_usage(p, end_ext_data,
    154                                                       &csr->key_usage)) != 0) {
    155                     return ret;
    156                 }
    157                 break;
    158 
    159             case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME:
    160                 /* Parse subject alt name */
    161                 if ((ret = mbedtls_x509_get_subject_alt_name(p, end_ext_data,
    162                                                              &csr->subject_alt_names)) != 0) {
    163                     return ret;
    164                 }
    165                 break;
    166 
    167             case MBEDTLS_X509_EXT_NS_CERT_TYPE:
    168                 /* Parse netscape certificate type */
    169                 if ((ret = mbedtls_x509_get_ns_cert_type(p, end_ext_data,
    170                                                          &csr->ns_cert_type)) != 0) {
    171                     return ret;
    172                 }
    173                 break;
    174             default:
    175                 /*
    176                  * If this is a non-critical extension, which the oid layer
    177                  * supports, but there isn't an x509 parser for it,
    178                  * skip the extension.
    179                  */
    180                 if (is_critical) {
    181                     return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
    182                 } else {
    183                     *p = end_ext_octet;
    184                 }
    185         }
    186     }
    187 
    188     if (*p != end) {
    189         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
    190                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
    191     }
    192 
    193     return 0;
    194 }
    195 
    196 /*
    197  * Parse CSR attributes in DER format
    198  */
    199 static int x509_csr_parse_attributes(mbedtls_x509_csr *csr,
    200                                      const unsigned char *start, const unsigned char *end,
    201                                      mbedtls_x509_csr_ext_cb_t cb,
    202                                      void *p_ctx)
    203 {
    204     int ret;
    205     size_t len;
    206     unsigned char *end_attr_data;
    207     unsigned char **p = (unsigned char **) &start;
    208 
    209     while (*p < end) {
    210         mbedtls_x509_buf attr_oid = { 0, 0, NULL };
    211 
    212         if ((ret = mbedtls_asn1_get_tag(p, end, &len,
    213                                         MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
    214             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
    215         }
    216         end_attr_data = *p + len;
    217 
    218         /* Get attribute ID */
    219         if ((ret = mbedtls_asn1_get_tag(p, end_attr_data, &attr_oid.len,
    220                                         MBEDTLS_ASN1_OID)) != 0) {
    221             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
    222         }
    223 
    224         attr_oid.tag = MBEDTLS_ASN1_OID;
    225         attr_oid.p = *p;
    226         *p += attr_oid.len;
    227 
    228         /* Check that this is an extension-request attribute */
    229         if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS9_CSR_EXT_REQ, &attr_oid) == 0) {
    230             if ((ret = mbedtls_asn1_get_tag(p, end, &len,
    231                                             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET)) != 0) {
    232                 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
    233             }
    234 
    235             if ((ret = mbedtls_asn1_get_tag(p, end, &len,
    236                                             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) !=
    237                 0) {
    238                 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
    239             }
    240 
    241             if ((ret = x509_csr_parse_extensions(csr, p, *p + len, cb, p_ctx)) != 0) {
    242                 return ret;
    243             }
    244 
    245             if (*p != end_attr_data) {
    246                 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
    247                                          MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
    248             }
    249         }
    250 
    251         *p = end_attr_data;
    252     }
    253 
    254     if (*p != end) {
    255         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
    256                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
    257     }
    258 
    259     return 0;
    260 }
    261 
    262 /*
    263  * Parse a CSR in DER format
    264  */
    265 static int mbedtls_x509_csr_parse_der_internal(mbedtls_x509_csr *csr,
    266                                                const unsigned char *buf, size_t buflen,
    267                                                mbedtls_x509_csr_ext_cb_t cb,
    268                                                void *p_ctx)
    269 {
    270     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    271     size_t len;
    272     unsigned char *p, *end;
    273     mbedtls_x509_buf sig_params;
    274 
    275     memset(&sig_params, 0, sizeof(mbedtls_x509_buf));
    276 
    277     /*
    278      * Check for valid input
    279      */
    280     if (csr == NULL || buf == NULL || buflen == 0) {
    281         return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
    282     }
    283 
    284     mbedtls_x509_csr_init(csr);
    285 
    286     /*
    287      * first copy the raw DER data
    288      */
    289     p = mbedtls_calloc(1, len = buflen);
    290 
    291     if (p == NULL) {
    292         return MBEDTLS_ERR_X509_ALLOC_FAILED;
    293     }
    294 
    295     memcpy(p, buf, buflen);
    296 
    297     csr->raw.p = p;
    298     csr->raw.len = len;
    299     end = p + len;
    300 
    301     /*
    302      *  CertificationRequest ::= SEQUENCE {
    303      *       certificationRequestInfo CertificationRequestInfo,
    304      *       signatureAlgorithm AlgorithmIdentifier,
    305      *       signature          BIT STRING
    306      *  }
    307      */
    308     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
    309                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
    310         mbedtls_x509_csr_free(csr);
    311         return MBEDTLS_ERR_X509_INVALID_FORMAT;
    312     }
    313 
    314     if (len != (size_t) (end - p)) {
    315         mbedtls_x509_csr_free(csr);
    316         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT,
    317                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
    318     }
    319 
    320     /*
    321      *  CertificationRequestInfo ::= SEQUENCE {
    322      */
    323     csr->cri.p = p;
    324 
    325     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
    326                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
    327         mbedtls_x509_csr_free(csr);
    328         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
    329     }
    330 
    331     end = p + len;
    332     csr->cri.len = (size_t) (end - csr->cri.p);
    333 
    334     /*
    335      *  Version  ::=  INTEGER {  v1(0) }
    336      */
    337     if ((ret = x509_csr_get_version(&p, end, &csr->version)) != 0) {
    338         mbedtls_x509_csr_free(csr);
    339         return ret;
    340     }
    341 
    342     if (csr->version != 0) {
    343         mbedtls_x509_csr_free(csr);
    344         return MBEDTLS_ERR_X509_UNKNOWN_VERSION;
    345     }
    346 
    347     csr->version++;
    348 
    349     /*
    350      *  subject               Name
    351      */
    352     csr->subject_raw.p = p;
    353 
    354     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
    355                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
    356         mbedtls_x509_csr_free(csr);
    357         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
    358     }
    359 
    360     if ((ret = mbedtls_x509_get_name(&p, p + len, &csr->subject)) != 0) {
    361         mbedtls_x509_csr_free(csr);
    362         return ret;
    363     }
    364 
    365     csr->subject_raw.len = (size_t) (p - csr->subject_raw.p);
    366 
    367     /*
    368      *  subjectPKInfo SubjectPublicKeyInfo
    369      */
    370     if ((ret = mbedtls_pk_parse_subpubkey(&p, end, &csr->pk)) != 0) {
    371         mbedtls_x509_csr_free(csr);
    372         return ret;
    373     }
    374 
    375     /*
    376      *  attributes    [0] Attributes
    377      *
    378      *  The list of possible attributes is open-ended, though RFC 2985
    379      *  (PKCS#9) defines a few in section 5.4. We currently don't support any,
    380      *  so we just ignore them. This is a safe thing to do as the worst thing
    381      *  that could happen is that we issue a certificate that does not match
    382      *  the requester's expectations - this cannot cause a violation of our
    383      *  signature policies.
    384      */
    385     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
    386                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC)) !=
    387         0) {
    388         mbedtls_x509_csr_free(csr);
    389         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
    390     }
    391 
    392     if ((ret = x509_csr_parse_attributes(csr, p, p + len, cb, p_ctx)) != 0) {
    393         mbedtls_x509_csr_free(csr);
    394         return ret;
    395     }
    396 
    397     p += len;
    398 
    399     end = csr->raw.p + csr->raw.len;
    400 
    401     /*
    402      *  signatureAlgorithm   AlgorithmIdentifier,
    403      *  signature            BIT STRING
    404      */
    405     if ((ret = mbedtls_x509_get_alg(&p, end, &csr->sig_oid, &sig_params)) != 0) {
    406         mbedtls_x509_csr_free(csr);
    407         return ret;
    408     }
    409 
    410     if ((ret = mbedtls_x509_get_sig_alg(&csr->sig_oid, &sig_params,
    411                                         &csr->sig_md, &csr->sig_pk,
    412                                         &csr->sig_opts)) != 0) {
    413         mbedtls_x509_csr_free(csr);
    414         return MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG;
    415     }
    416 
    417     if ((ret = mbedtls_x509_get_sig(&p, end, &csr->sig)) != 0) {
    418         mbedtls_x509_csr_free(csr);
    419         return ret;
    420     }
    421 
    422     if (p != end) {
    423         mbedtls_x509_csr_free(csr);
    424         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT,
    425                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
    426     }
    427 
    428     return 0;
    429 }
    430 
    431 /*
    432  * Parse a CSR in DER format
    433  */
    434 int mbedtls_x509_csr_parse_der(mbedtls_x509_csr *csr,
    435                                const unsigned char *buf, size_t buflen)
    436 {
    437     return mbedtls_x509_csr_parse_der_internal(csr, buf, buflen, NULL, NULL);
    438 }
    439 
    440 /*
    441  * Parse a CSR in DER format with callback for unknown extensions
    442  */
    443 int mbedtls_x509_csr_parse_der_with_ext_cb(mbedtls_x509_csr *csr,
    444                                            const unsigned char *buf, size_t buflen,
    445                                            mbedtls_x509_csr_ext_cb_t cb,
    446                                            void *p_ctx)
    447 {
    448     return mbedtls_x509_csr_parse_der_internal(csr, buf, buflen, cb, p_ctx);
    449 }
    450 
    451 /*
    452  * Parse a CSR, allowing for PEM or raw DER encoding
    453  */
    454 int mbedtls_x509_csr_parse(mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen)
    455 {
    456 #if defined(MBEDTLS_PEM_PARSE_C)
    457     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    458     size_t use_len;
    459     mbedtls_pem_context pem;
    460 #endif
    461 
    462     /*
    463      * Check for valid input
    464      */
    465     if (csr == NULL || buf == NULL || buflen == 0) {
    466         return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
    467     }
    468 
    469 #if defined(MBEDTLS_PEM_PARSE_C)
    470     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
    471     if (buf[buflen - 1] == '\0') {
    472         mbedtls_pem_init(&pem);
    473         ret = mbedtls_pem_read_buffer(&pem,
    474                                       "-----BEGIN CERTIFICATE REQUEST-----",
    475                                       "-----END CERTIFICATE REQUEST-----",
    476                                       buf, NULL, 0, &use_len);
    477         if (ret == MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) {
    478             ret = mbedtls_pem_read_buffer(&pem,
    479                                           "-----BEGIN NEW CERTIFICATE REQUEST-----",
    480                                           "-----END NEW CERTIFICATE REQUEST-----",
    481                                           buf, NULL, 0, &use_len);
    482         }
    483 
    484         if (ret == 0) {
    485             /*
    486              * Was PEM encoded, parse the result
    487              */
    488             ret = mbedtls_x509_csr_parse_der(csr, pem.buf, pem.buflen);
    489         }
    490 
    491         mbedtls_pem_free(&pem);
    492         if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) {
    493             return ret;
    494         }
    495     }
    496 #endif /* MBEDTLS_PEM_PARSE_C */
    497     return mbedtls_x509_csr_parse_der(csr, buf, buflen);
    498 }
    499 
    500 #if defined(MBEDTLS_FS_IO)
    501 /*
    502  * Load a CSR into the structure
    503  */
    504 int mbedtls_x509_csr_parse_file(mbedtls_x509_csr *csr, const char *path)
    505 {
    506     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    507     size_t n;
    508     unsigned char *buf;
    509 
    510     if ((ret = mbedtls_pk_load_file(path, &buf, &n)) != 0) {
    511         return ret;
    512     }
    513 
    514     ret = mbedtls_x509_csr_parse(csr, buf, n);
    515 
    516     mbedtls_zeroize_and_free(buf, n);
    517 
    518     return ret;
    519 }
    520 #endif /* MBEDTLS_FS_IO */
    521 
    522 #if !defined(MBEDTLS_X509_REMOVE_INFO)
    523 #define BEFORE_COLON    14
    524 #define BC              "14"
    525 /*
    526  * Return an informational string about the CSR.
    527  */
    528 int mbedtls_x509_csr_info(char *buf, size_t size, const char *prefix,
    529                           const mbedtls_x509_csr *csr)
    530 {
    531     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    532     size_t n;
    533     char *p;
    534     char key_size_str[BEFORE_COLON];
    535 
    536     p = buf;
    537     n = size;
    538 
    539     ret = mbedtls_snprintf(p, n, "%sCSR version   : %d",
    540                            prefix, csr->version);
    541     MBEDTLS_X509_SAFE_SNPRINTF;
    542 
    543     ret = mbedtls_snprintf(p, n, "\n%ssubject name  : ", prefix);
    544     MBEDTLS_X509_SAFE_SNPRINTF;
    545     ret = mbedtls_x509_dn_gets(p, n, &csr->subject);
    546     MBEDTLS_X509_SAFE_SNPRINTF;
    547 
    548     ret = mbedtls_snprintf(p, n, "\n%ssigned using  : ", prefix);
    549     MBEDTLS_X509_SAFE_SNPRINTF;
    550 
    551     ret = mbedtls_x509_sig_alg_gets(p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md,
    552                                     csr->sig_opts);
    553     MBEDTLS_X509_SAFE_SNPRINTF;
    554 
    555     if ((ret = mbedtls_x509_key_size_helper(key_size_str, BEFORE_COLON,
    556                                             mbedtls_pk_get_name(&csr->pk))) != 0) {
    557         return ret;
    558     }
    559 
    560     ret = mbedtls_snprintf(p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str,
    561                            (int) mbedtls_pk_get_bitlen(&csr->pk));
    562     MBEDTLS_X509_SAFE_SNPRINTF;
    563 
    564     /*
    565      * Optional extensions
    566      */
    567 
    568     if (csr->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME) {
    569         ret = mbedtls_snprintf(p, n, "\n%ssubject alt name  :", prefix);
    570         MBEDTLS_X509_SAFE_SNPRINTF;
    571 
    572         if ((ret = mbedtls_x509_info_subject_alt_name(&p, &n,
    573                                                       &csr->subject_alt_names,
    574                                                       prefix)) != 0) {
    575             return ret;
    576         }
    577     }
    578 
    579     if (csr->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE) {
    580         ret = mbedtls_snprintf(p, n, "\n%scert. type        : ", prefix);
    581         MBEDTLS_X509_SAFE_SNPRINTF;
    582 
    583         if ((ret = mbedtls_x509_info_cert_type(&p, &n, csr->ns_cert_type)) != 0) {
    584             return ret;
    585         }
    586     }
    587 
    588     if (csr->ext_types & MBEDTLS_X509_EXT_KEY_USAGE) {
    589         ret = mbedtls_snprintf(p, n, "\n%skey usage         : ", prefix);
    590         MBEDTLS_X509_SAFE_SNPRINTF;
    591 
    592         if ((ret = mbedtls_x509_info_key_usage(&p, &n, csr->key_usage)) != 0) {
    593             return ret;
    594         }
    595     }
    596 
    597     if (csr->ext_types != 0) {
    598         ret = mbedtls_snprintf(p, n, "\n");
    599         MBEDTLS_X509_SAFE_SNPRINTF;
    600     }
    601 
    602     return (int) (size - n);
    603 }
    604 #endif /* MBEDTLS_X509_REMOVE_INFO */
    605 
    606 /*
    607  * Initialize a CSR
    608  */
    609 void mbedtls_x509_csr_init(mbedtls_x509_csr *csr)
    610 {
    611     memset(csr, 0, sizeof(mbedtls_x509_csr));
    612 }
    613 
    614 /*
    615  * Unallocate all CSR data
    616  */
    617 void mbedtls_x509_csr_free(mbedtls_x509_csr *csr)
    618 {
    619     if (csr == NULL) {
    620         return;
    621     }
    622 
    623     mbedtls_pk_free(&csr->pk);
    624 
    625 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
    626     mbedtls_free(csr->sig_opts);
    627 #endif
    628 
    629     mbedtls_asn1_free_named_data_list_shallow(csr->subject.next);
    630     mbedtls_asn1_sequence_free(csr->subject_alt_names.next);
    631 
    632     if (csr->raw.p != NULL) {
    633         mbedtls_zeroize_and_free(csr->raw.p, csr->raw.len);
    634     }
    635 
    636     mbedtls_platform_zeroize(csr, sizeof(mbedtls_x509_csr));
    637 }
    638 
    639 #endif /* MBEDTLS_X509_CSR_PARSE_C */