LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib/x509 - extensions.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 278 398 69.8 %
Date: 2020-10-30 04:50:48 Functions: 19 22 86.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2003-2014 Free Software Foundation, Inc.
       3             :  *
       4             :  * Author: Nikos Mavrogiannopoulos
       5             :  *
       6             :  * This file is part of GnuTLS.
       7             :  *
       8             :  * The GnuTLS is free software; you can redistribute it and/or
       9             :  * modify it under the terms of the GNU Lesser General Public License
      10             :  * as published by the Free Software Foundation; either version 2.1 of
      11             :  * the License, or (at your option) any later version.
      12             :  *
      13             :  * This library is distributed in the hope that it will be useful, but
      14             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :  * Lesser General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU Lesser General Public License
      19             :  * along with this program.  If not, see <https://www.gnu.org/licenses/>
      20             :  *
      21             :  */
      22             : 
      23             : /* Functions that relate to the X.509 extension parsing.
      24             :  */
      25             : 
      26             : #include "gnutls_int.h"
      27             : #include "errors.h"
      28             : #include <global.h>
      29             : #include <libtasn1.h>
      30             : #include <common.h>
      31             : #include <gnutls/x509-ext.h>
      32             : #include <gnutls/x509.h>
      33             : #include <x509_int.h>
      34             : #include <datum.h>
      35             : 
      36             : int
      37       99091 : _gnutls_get_extension(ASN1_TYPE asn, const char *root,
      38             :               const char *extension_id, int indx,
      39             :               gnutls_datum_t * ret, unsigned int *_critical)
      40             : {
      41       99091 :         int k, result, len;
      42       99091 :         char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE];
      43       99091 :         char str_critical[10];
      44       99091 :         int critical = 0;
      45       99091 :         char extnID[MAX_OID_SIZE];
      46       99091 :         gnutls_datum_t value;
      47       99091 :         int indx_counter = 0;
      48             : 
      49       99091 :         ret->data = NULL;
      50       99091 :         ret->size = 0;
      51             : 
      52       99091 :         k = 0;
      53      406858 :         do {
      54      406858 :                 k++;
      55             : 
      56      406858 :                 snprintf(name, sizeof(name), "%s.?%u", root, k);
      57             : 
      58      406858 :                 _gnutls_str_cpy(name2, sizeof(name2), name);
      59      406858 :                 _gnutls_str_cat(name2, sizeof(name2), ".extnID");
      60             : 
      61      406858 :                 len = sizeof(extnID) - 1;
      62      406858 :                 result = asn1_read_value(asn, name2, extnID, &len);
      63             : 
      64      406858 :                 if (result == ASN1_ELEMENT_NOT_FOUND) {
      65             :                         break;
      66      355353 :                 } else if (result != ASN1_SUCCESS) {
      67           4 :                         gnutls_assert();
      68           4 :                         return _gnutls_asn2err(result);
      69             :                 }
      70             : 
      71             :                 /* Handle Extension 
      72             :                  */
      73      355349 :                 if (strcmp(extnID, extension_id) == 0
      74       47582 :                     && indx == indx_counter++) {
      75             :                         /* extension was found 
      76             :                          */
      77             : 
      78             :                         /* read the critical status.
      79             :                          */
      80       47582 :                         _gnutls_str_cpy(name2, sizeof(name2), name);
      81       47582 :                         _gnutls_str_cat(name2, sizeof(name2), ".critical");
      82             : 
      83       47582 :                         len = sizeof(str_critical);
      84       47582 :                         result =
      85       47582 :                             asn1_read_value(asn, name2,
      86             :                                             str_critical, &len);
      87             : 
      88       47582 :                         if (result == ASN1_ELEMENT_NOT_FOUND) {
      89           0 :                                 gnutls_assert();
      90             :                                 break;
      91       47582 :                         } else if (result != ASN1_SUCCESS) {
      92           0 :                                 gnutls_assert();
      93           0 :                                 return _gnutls_asn2err(result);
      94             :                         }
      95             : 
      96       47582 :                         if (str_critical[0] == 'T')
      97             :                                 critical = 1;
      98             :                         else
      99       23945 :                                 critical = 0;
     100             : 
     101             :                         /* read the value.
     102             :                          */
     103       47582 :                         _gnutls_str_cpy(name2, sizeof(name2), name);
     104       47582 :                         _gnutls_str_cat(name2, sizeof(name2),
     105             :                                         ".extnValue");
     106             : 
     107       47582 :                         result =
     108       47582 :                             _gnutls_x509_read_value(asn, name2, &value);
     109       47582 :                         if (result < 0) {
     110           5 :                                 gnutls_assert();
     111           5 :                                 return result;
     112             :                         }
     113             : 
     114       47577 :                         ret->data = value.data;
     115       47577 :                         ret->size = value.size;
     116             : 
     117       47577 :                         if (_critical)
     118         943 :                                 *_critical = critical;
     119             : 
     120       47577 :                         return 0;
     121             :                 }
     122             :         }
     123             :         while (1);
     124             : 
     125       51505 :         if (result == ASN1_ELEMENT_NOT_FOUND) {
     126             :                 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
     127             :         } else {
     128           0 :                 gnutls_assert();
     129           0 :                 return _gnutls_asn2err(result);
     130             :         }
     131             : }
     132             : 
     133             : static int
     134        4397 : get_indx_extension(ASN1_TYPE asn, const char *root,
     135             :               int indx, gnutls_datum_t * out)
     136             : {
     137        4397 :         char name[MAX_NAME_SIZE];
     138        4397 :         int ret;
     139             : 
     140        4397 :         out->data = NULL;
     141        4397 :         out->size = 0;
     142             : 
     143        4397 :         snprintf(name, sizeof(name), "%s.?%u.extnValue", root, indx+1);
     144             : 
     145        4397 :         ret = _gnutls_x509_read_value(asn, name, out);
     146        4397 :         if (ret < 0)
     147           8 :                 return gnutls_assert_val(ret);
     148             : 
     149             :         return 0;
     150             : }
     151             : 
     152             : int
     153       98708 : _gnutls_x509_crt_get_extension(gnutls_x509_crt_t cert,
     154             :                                const char *extension_id, int indx,
     155             :                                gnutls_datum_t * data, unsigned int *critical)
     156             : {
     157       98708 :         return _gnutls_get_extension(cert->cert, "tbsCertificate.extensions",
     158             :                              extension_id, indx, data, critical);
     159             : }
     160             : 
     161             : /**
     162             :  * gnutls_x509_crt_get_extension_data2:
     163             :  * @cert: should contain a #gnutls_x509_crt_t type
     164             :  * @indx: Specifies which extension OID to read. Use (0) to get the first one.
     165             :  * @data: will contain the extension DER-encoded data
     166             :  *
     167             :  * This function will return the requested by the index extension data in the
     168             :  * certificate.  The extension data will be allocated using
     169             :  * gnutls_malloc().
     170             :  *
     171             :  * Use gnutls_x509_crt_get_extension_info() to extract the OID.
     172             :  *
     173             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
     174             :  *   otherwise a negative error code is returned.  If you have reached the
     175             :  *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
     176             :  *   will be returned.
     177             :  **/
     178             : int
     179        4176 : gnutls_x509_crt_get_extension_data2(gnutls_x509_crt_t cert,
     180             :                                unsigned indx,
     181             :                                gnutls_datum_t * data)
     182             : {
     183        4176 :         return get_indx_extension(cert->cert, "tbsCertificate.extensions",
     184             :                              indx, data);
     185             : }
     186             : 
     187             : int
     188         366 : _gnutls_x509_crl_get_extension(gnutls_x509_crl_t crl,
     189             :                                const char *extension_id, int indx,
     190             :                                gnutls_datum_t * data,
     191             :                                unsigned int *critical)
     192             : {
     193         366 :         return _gnutls_get_extension(crl->crl, "tbsCertList.crlExtensions",
     194             :                              extension_id, indx, data, critical);
     195             : }
     196             : 
     197             : /**
     198             :  * gnutls_x509_crl_get_extension_data2:
     199             :  * @crl: should contain a #gnutls_x509_crl_t type
     200             :  * @indx: Specifies which extension OID to read. Use (0) to get the first one.
     201             :  * @data: will contain the extension DER-encoded data
     202             :  *
     203             :  * This function will return the requested by the index extension data in the
     204             :  * certificate revocation list.  The extension data will be allocated using
     205             :  * gnutls_malloc().
     206             :  *
     207             :  * Use gnutls_x509_crt_get_extension_info() to extract the OID.
     208             :  *
     209             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
     210             :  *   otherwise a negative error code is returned.  If you have reached the
     211             :  *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
     212             :  *   will be returned.
     213             :  **/
     214             : int
     215         221 : gnutls_x509_crl_get_extension_data2(gnutls_x509_crl_t crl,
     216             :                                unsigned indx,
     217             :                                gnutls_datum_t * data)
     218             : {
     219         221 :         return get_indx_extension(crl->crl, "tbsCertList.crlExtensions",
     220             :                              indx, data);
     221             : }
     222             : 
     223             : /* This function will attempt to return the requested extension OID found in
     224             :  * the given X509v3 certificate. 
     225             :  *
     226             :  * If you have passed the last extension, GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
     227             :  * be returned.
     228             :  */
     229           0 : static int get_extension_oid(ASN1_TYPE asn, const char *root,
     230             :                   unsigned indx, void *oid, size_t * sizeof_oid)
     231             : {
     232           0 :         int k, result, len;
     233           0 :         char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE];
     234           0 :         char extnID[MAX_OID_SIZE];
     235           0 :         unsigned indx_counter = 0;
     236             : 
     237           0 :         k = 0;
     238           0 :         do {
     239           0 :                 k++;
     240             : 
     241           0 :                 snprintf(name, sizeof(name), "%s.?%u", root, k);
     242             : 
     243           0 :                 _gnutls_str_cpy(name2, sizeof(name2), name);
     244           0 :                 _gnutls_str_cat(name2, sizeof(name2), ".extnID");
     245             : 
     246           0 :                 len = sizeof(extnID) - 1;
     247           0 :                 result = asn1_read_value(asn, name2, extnID, &len);
     248             : 
     249           0 :                 if (result == ASN1_ELEMENT_NOT_FOUND) {
     250           0 :                         gnutls_assert();
     251           0 :                         break;
     252           0 :                 } else if (result != ASN1_SUCCESS) {
     253           0 :                         gnutls_assert();
     254           0 :                         return _gnutls_asn2err(result);
     255             :                 }
     256             : 
     257             :                 /* Handle Extension 
     258             :                  */
     259           0 :                 if (indx == indx_counter++) {
     260           0 :                         len = strlen(extnID) + 1;
     261             : 
     262           0 :                         if (*sizeof_oid < (unsigned) len) {
     263           0 :                                 *sizeof_oid = len;
     264           0 :                                 gnutls_assert();
     265           0 :                                 return GNUTLS_E_SHORT_MEMORY_BUFFER;
     266             :                         }
     267             : 
     268           0 :                         memcpy(oid, extnID, len);
     269           0 :                         *sizeof_oid = len - 1;
     270             : 
     271           0 :                         return 0;
     272             :                 }
     273             : 
     274             : 
     275             :         }
     276             :         while (1);
     277             : 
     278           0 :         if (result == ASN1_ELEMENT_NOT_FOUND) {
     279           0 :                 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
     280             :         } else {
     281             :                 gnutls_assert();
     282             :                 return _gnutls_asn2err(result);
     283             :         }
     284             : }
     285             : 
     286             : /* This function will attempt to return the requested extension OID found in
     287             :  * the given X509v3 certificate. 
     288             :  *
     289             :  * If you have passed the last extension, GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
     290             :  * be returned.
     291             :  */
     292             : int
     293           0 : _gnutls_x509_crt_get_extension_oid(gnutls_x509_crt_t cert,
     294             :                                    int indx, void *oid,
     295             :                                    size_t * sizeof_oid)
     296             : {
     297           0 :         return get_extension_oid(cert->cert, "tbsCertificate.extensions",
     298             :                                  indx, oid, sizeof_oid);
     299             : }
     300             : 
     301             : int
     302           0 : _gnutls_x509_crl_get_extension_oid(gnutls_x509_crl_t crl,
     303             :                                    int indx, void *oid,
     304             :                                    size_t * sizeof_oid)
     305             : {
     306           0 :         return get_extension_oid(crl->crl, "tbsCertList.crlExtensions",
     307             :                                  indx, oid, sizeof_oid);
     308             : }
     309             : 
     310             : /* This function will attempt to set the requested extension in
     311             :  * the given X509v3 certificate. 
     312             :  *
     313             :  * Critical will be either 0 or 1.
     314             :  */
     315             : static int
     316         609 : add_extension(ASN1_TYPE asn, const char *root, const char *extension_id,
     317             :               const gnutls_datum_t * ext_data, unsigned int critical)
     318             : {
     319         609 :         int result;
     320         609 :         const char *str;
     321         609 :         char name[MAX_NAME_SIZE];
     322             : 
     323         609 :         snprintf(name, sizeof(name), "%s", root);
     324             : 
     325             :         /* Add a new extension in the list.
     326             :          */
     327         609 :         result = asn1_write_value(asn, name, "NEW", 1);
     328         609 :         if (result != ASN1_SUCCESS) {
     329           0 :                 gnutls_assert();
     330           0 :                 return _gnutls_asn2err(result);
     331             :         }
     332             : 
     333         609 :         if (root[0] != 0)
     334         561 :                 snprintf(name, sizeof(name), "%s.?LAST.extnID", root);
     335             :         else
     336          48 :                 snprintf(name, sizeof(name), "?LAST.extnID");
     337             : 
     338         609 :         result = asn1_write_value(asn, name, extension_id, 1);
     339         609 :         if (result != ASN1_SUCCESS) {
     340           0 :                 gnutls_assert();
     341           0 :                 return _gnutls_asn2err(result);
     342             :         }
     343             : 
     344         609 :         if (critical == 0)
     345             :                 str = "FALSE";
     346             :         else
     347         217 :                 str = "TRUE";
     348             : 
     349         609 :         if (root[0] != 0)
     350         561 :                 snprintf(name, sizeof(name), "%s.?LAST.critical", root);
     351             :         else
     352          48 :                 snprintf(name, sizeof(name), "?LAST.critical");
     353             : 
     354         609 :         result = asn1_write_value(asn, name, str, 1);
     355         609 :         if (result != ASN1_SUCCESS) {
     356           0 :                 gnutls_assert();
     357           0 :                 return _gnutls_asn2err(result);
     358             :         }
     359             : 
     360         609 :         if (root[0] != 0)
     361         561 :                 snprintf(name, sizeof(name), "%s.?LAST.extnValue", root);
     362             :         else
     363          48 :                 snprintf(name, sizeof(name), "?LAST.extnValue");
     364             : 
     365         609 :         result = _gnutls_x509_write_value(asn, name, ext_data);
     366         609 :         if (result < 0) {
     367           0 :                 gnutls_assert();
     368           0 :                 return result;
     369             :         }
     370             : 
     371             :         return 0;
     372             : }
     373             : 
     374             : /* Overwrite the given extension (using the index)
     375             :  * index here starts from one.
     376             :  */
     377             : static int
     378         396 : overwrite_extension(ASN1_TYPE asn, const char *root, unsigned int indx,
     379             :                     const gnutls_datum_t * ext_data, unsigned int critical)
     380             : {
     381         396 :         char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE];
     382         396 :         const char *str;
     383         396 :         int result;
     384             : 
     385         396 :         if (root[0] != 0)
     386         380 :                 snprintf(name, sizeof(name), "%s.?%u", root, indx);
     387             :         else
     388          16 :                 snprintf(name, sizeof(name), "?%u", indx);
     389             : 
     390         396 :         if (critical == 0)
     391             :                 str = "FALSE";
     392             :         else
     393          15 :                 str = "TRUE";
     394             : 
     395         396 :         _gnutls_str_cpy(name2, sizeof(name2), name);
     396         396 :         _gnutls_str_cat(name2, sizeof(name2), ".critical");
     397             : 
     398         396 :         result = asn1_write_value(asn, name2, str, 1);
     399         396 :         if (result != ASN1_SUCCESS) {
     400           0 :                 gnutls_assert();
     401           0 :                 return _gnutls_asn2err(result);
     402             :         }
     403             : 
     404         396 :         _gnutls_str_cpy(name2, sizeof(name2), name);
     405         396 :         _gnutls_str_cat(name2, sizeof(name2), ".extnValue");
     406             : 
     407         396 :         result = _gnutls_x509_write_value(asn, name2, ext_data);
     408         396 :         if (result < 0) {
     409           0 :                 gnutls_assert();
     410           0 :                 return result;
     411             :         }
     412             : 
     413             :         return 0;
     414             : }
     415             : 
     416             : int
     417        1005 : _gnutls_set_extension(ASN1_TYPE asn, const char *root,
     418             :               const char *ext_id,
     419             :               const gnutls_datum_t * ext_data, unsigned int critical)
     420             : {
     421        1005 :         int result = 0;
     422        1005 :         int k, len;
     423        1005 :         char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE];
     424        1005 :         char extnID[MAX_OID_SIZE];
     425             : 
     426             :         /* Find the index of the given extension.
     427             :          */
     428        1005 :         k = 0;
     429        3323 :         do {
     430        3323 :                 k++;
     431             : 
     432        3323 :                 if (root[0] != 0)
     433        3085 :                         snprintf(name, sizeof(name), "%s.?%u", root, k);
     434             :                 else
     435         238 :                         snprintf(name, sizeof(name), "?%u", k);
     436             : 
     437        3323 :                 len = sizeof(extnID) - 1;
     438        3323 :                 result = asn1_read_value(asn, name, extnID, &len);
     439             : 
     440             :                 /* move to next
     441             :                  */
     442             : 
     443        3323 :                 if (result == ASN1_ELEMENT_NOT_FOUND) {
     444             :                         break;
     445             :                 }
     446             : 
     447        2714 :                 do {
     448             : 
     449        2714 :                         _gnutls_str_cpy(name2, sizeof(name2), name);
     450        2714 :                         _gnutls_str_cat(name2, sizeof(name2), ".extnID");
     451             : 
     452        2714 :                         len = sizeof(extnID) - 1;
     453        2714 :                         result = asn1_read_value(asn, name2, extnID, &len);
     454             : 
     455        2714 :                         if (result == ASN1_ELEMENT_NOT_FOUND) {
     456           0 :                                 gnutls_assert();
     457             :                                 break;
     458        2714 :                         } else if (result != ASN1_SUCCESS) {
     459           0 :                                 gnutls_assert();
     460           0 :                                 return _gnutls_asn2err(result);
     461             :                         }
     462             : 
     463             :                         /* Handle Extension 
     464             :                          */
     465        2714 :                         if (strcmp(extnID, ext_id) == 0) {
     466             :                                 /* extension was found 
     467             :                                  */
     468         396 :                                 return overwrite_extension(asn, root, k,
     469             :                                                            ext_data,
     470             :                                                            critical);
     471             :                         }
     472             : 
     473             : 
     474             :                 }
     475             :                 while (0);
     476             :         }
     477             :         while (1);
     478             : 
     479         609 :         if (result == ASN1_ELEMENT_NOT_FOUND) {
     480         609 :                 return add_extension(asn, root, ext_id, ext_data,
     481             :                                      critical);
     482             :         } else {
     483             :                 gnutls_assert();
     484             :                 return _gnutls_asn2err(result);
     485             :         }
     486             : 
     487             : 
     488             :         return 0;
     489             : }
     490             : 
     491             : /* This function will attempt to overwrite the requested extension with
     492             :  * the given one. 
     493             :  *
     494             :  * Critical will be either 0 or 1.
     495             :  */
     496             : int
     497         916 : _gnutls_x509_crt_set_extension(gnutls_x509_crt_t cert,
     498             :                                const char *ext_id,
     499             :                                const gnutls_datum_t * ext_data,
     500             :                                unsigned int critical)
     501             : {
     502         916 :         MODIFIED(cert);
     503         916 :         cert->use_extensions = 1;
     504             : 
     505         916 :         return _gnutls_set_extension(cert->cert, "tbsCertificate.extensions",
     506             :                              ext_id, ext_data, critical);
     507             : }
     508             : 
     509             : int
     510          16 : _gnutls_x509_crl_set_extension(gnutls_x509_crl_t crl,
     511             :                                const char *ext_id,
     512             :                                const gnutls_datum_t * ext_data,
     513             :                                unsigned int critical)
     514             : {
     515          16 :         return _gnutls_set_extension(crl->crl, "tbsCertList.crlExtensions", ext_id,
     516             :                              ext_data, critical);
     517             : }
     518             : 
     519             : int
     520          64 : _gnutls_x509_crq_set_extension(gnutls_x509_crq_t crq,
     521             :                                const char *ext_id,
     522             :                                const gnutls_datum_t * ext_data,
     523             :                                unsigned int critical)
     524             : {
     525          64 :         unsigned char *extensions = NULL;
     526          64 :         size_t extensions_size = 0;
     527          64 :         gnutls_datum_t der;
     528          64 :         ASN1_TYPE c2;
     529          64 :         int result;
     530             : 
     531          64 :         result =
     532          64 :             gnutls_x509_crq_get_attribute_by_oid(crq,
     533             :                                                  "1.2.840.113549.1.9.14",
     534             :                                                  0, NULL,
     535             :                                                  &extensions_size);
     536          64 :         if (result == GNUTLS_E_SHORT_MEMORY_BUFFER) {
     537          56 :                 extensions = gnutls_malloc(extensions_size);
     538          56 :                 if (extensions == NULL) {
     539           0 :                         gnutls_assert();
     540           0 :                         return GNUTLS_E_MEMORY_ERROR;
     541             :                 }
     542             : 
     543          56 :                 result = gnutls_x509_crq_get_attribute_by_oid(crq,
     544             :                                                               "1.2.840.113549.1.9.14",
     545             :                                                               0,
     546             :                                                               extensions,
     547             :                                                               &extensions_size);
     548             :         }
     549          64 :         if (result < 0) {
     550           8 :                 if (result == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
     551           8 :                         extensions_size = 0;
     552             :                 } else {
     553           0 :                         gnutls_assert();
     554           0 :                         gnutls_free(extensions);
     555           0 :                         return result;
     556             :                 }
     557             :         }
     558             : 
     559          64 :         result =
     560          64 :             asn1_create_element(_gnutls_get_pkix(), "PKIX1.Extensions",
     561             :                                 &c2);
     562          64 :         if (result != ASN1_SUCCESS) {
     563           0 :                 gnutls_assert();
     564           0 :                 gnutls_free(extensions);
     565           0 :                 return _gnutls_asn2err(result);
     566             :         }
     567             : 
     568          64 :         if (extensions_size > 0) {
     569          56 :                 result =
     570          56 :                     _asn1_strict_der_decode(&c2, extensions, extensions_size,
     571             :                                       NULL);
     572          56 :                 gnutls_free(extensions);
     573          56 :                 if (result != ASN1_SUCCESS) {
     574           0 :                         gnutls_assert();
     575           0 :                         asn1_delete_structure(&c2);
     576           0 :                         return _gnutls_asn2err(result);
     577             :                 }
     578             :         }
     579             : 
     580          64 :         result = _gnutls_set_extension(c2, "", ext_id, ext_data, critical);
     581          64 :         if (result < 0) {
     582           0 :                 gnutls_assert();
     583           0 :                 asn1_delete_structure(&c2);
     584           0 :                 return result;
     585             :         }
     586             : 
     587          64 :         result = _gnutls_x509_der_encode(c2, "", &der, 0);
     588             : 
     589          64 :         asn1_delete_structure(&c2);
     590             : 
     591          64 :         if (result < 0) {
     592           0 :                 gnutls_assert();
     593           0 :                 return result;
     594             :         }
     595             : 
     596          64 :         result =
     597         128 :             gnutls_x509_crq_set_attribute_by_oid(crq,
     598             :                                                  "1.2.840.113549.1.9.14",
     599          64 :                                                  der.data, der.size);
     600          64 :         gnutls_free(der.data);
     601          64 :         if (result < 0) {
     602           0 :                 gnutls_assert();
     603           0 :                 return result;
     604             :         }
     605             : 
     606             : 
     607             :         return 0;
     608             : }
     609             : 
     610             : /* extract an INTEGER from the DER encoded extension
     611             :  */
     612             : int
     613         350 : _gnutls_x509_ext_extract_number(uint8_t * number,
     614             :                                 size_t * _nr_size,
     615             :                                 uint8_t * extnValue, int extnValueLen)
     616             : {
     617         350 :         ASN1_TYPE ext = ASN1_TYPE_EMPTY;
     618         350 :         int result;
     619         350 :         int nr_size = *_nr_size;
     620             : 
     621             :         /* here it doesn't matter so much that we use CertificateSerialNumber. It is equal
     622             :          * to using INTEGER.
     623             :          */
     624         350 :         if ((result = asn1_create_element
     625             :              (_gnutls_get_pkix(), "PKIX1.CertificateSerialNumber",
     626             :               &ext)) != ASN1_SUCCESS) {
     627           0 :                 gnutls_assert();
     628           0 :                 return _gnutls_asn2err(result);
     629             :         }
     630             : 
     631         350 :         result = _asn1_strict_der_decode(&ext, extnValue, extnValueLen, NULL);
     632         350 :         if (result != ASN1_SUCCESS) {
     633           0 :                 gnutls_assert();
     634           0 :                 asn1_delete_structure(&ext);
     635           0 :                 return _gnutls_asn2err(result);
     636             :         }
     637             : 
     638             :         /* the default value of cA is false.
     639             :          */
     640         350 :         result = asn1_read_value(ext, "", number, &nr_size);
     641         350 :         if (result != ASN1_SUCCESS)
     642           0 :                 result = _gnutls_asn2err(result);
     643             :         else
     644             :                 result = 0;
     645             : 
     646         350 :         *_nr_size = nr_size;
     647             : 
     648         350 :         asn1_delete_structure(&ext);
     649             : 
     650         350 :         return result;
     651             : }
     652             : 
     653             : /* generate an INTEGER in a DER encoded extension
     654             :  */
     655             : int
     656         525 : _gnutls_x509_ext_gen_number(const uint8_t * number, size_t nr_size,
     657             :                             gnutls_datum_t * der_ext)
     658             : {
     659         525 :         ASN1_TYPE ext = ASN1_TYPE_EMPTY;
     660         525 :         int result;
     661             : 
     662         525 :         result =
     663         525 :             asn1_create_element(_gnutls_get_pkix(),
     664             :                                 "PKIX1.CertificateSerialNumber", &ext);
     665         525 :         if (result != ASN1_SUCCESS) {
     666           0 :                 gnutls_assert();
     667           0 :                 return _gnutls_asn2err(result);
     668             :         }
     669             : 
     670         525 :         result = asn1_write_value(ext, "", number, nr_size);
     671         525 :         if (result != ASN1_SUCCESS) {
     672           0 :                 gnutls_assert();
     673           0 :                 asn1_delete_structure(&ext);
     674           0 :                 return _gnutls_asn2err(result);
     675             :         }
     676             : 
     677         525 :         result = _gnutls_x509_der_encode(ext, "", der_ext, 0);
     678             : 
     679         525 :         asn1_delete_structure(&ext);
     680             : 
     681         525 :         if (result < 0) {
     682           0 :                 gnutls_assert();
     683           0 :                 return result;
     684             :         }
     685             : 
     686             :         return 0;
     687             : }
     688             : 
     689             : int
     690        1474 : _gnutls_write_general_name(ASN1_TYPE ext, const char *ext_name,
     691             :                        gnutls_x509_subject_alt_name_t type,
     692             :                        const void *data, unsigned int data_size)
     693             : {
     694        1474 :         const char *str;
     695        1474 :         int result;
     696        1474 :         char name[128];
     697             : 
     698        1474 :         if (data == NULL) {
     699           1 :                 if (data_size == 0)
     700             :                         data = (void*)"";
     701             :                 else
     702           0 :                         return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     703             :         }
     704             : 
     705        1474 :         switch (type) {
     706             :         case GNUTLS_SAN_DNSNAME:
     707             :                 str = "dNSName";
     708             :                 break;
     709         177 :         case GNUTLS_SAN_RFC822NAME:
     710         177 :                 str = "rfc822Name";
     711         177 :                 break;
     712         235 :         case GNUTLS_SAN_URI:
     713         235 :                 str = "uniformResourceIdentifier";
     714         235 :                 break;
     715         196 :         case GNUTLS_SAN_IPADDRESS:
     716         196 :                 str = "iPAddress";
     717         196 :                 break;
     718           3 :         case GNUTLS_SAN_REGISTERED_ID:
     719           3 :                 str = "registeredID";
     720           3 :                 break;
     721           0 :         default:
     722           0 :                 gnutls_assert();
     723             :                 return GNUTLS_E_INTERNAL_ERROR;
     724             :         }
     725             : 
     726        1474 :         result = asn1_write_value(ext, ext_name, str, 1);
     727        1474 :         if (result != ASN1_SUCCESS) {
     728           0 :                 gnutls_assert();
     729           0 :                 return _gnutls_asn2err(result);
     730             :         }
     731             : 
     732        1474 :         snprintf(name, sizeof(name), "%s.%s", ext_name, str);
     733             : 
     734        1474 :         result = asn1_write_value(ext, name, data, data_size);
     735        1474 :         if (result != ASN1_SUCCESS) {
     736           0 :                 gnutls_assert();
     737           0 :                 asn1_delete_structure(&ext);
     738           0 :                 return _gnutls_asn2err(result);
     739             :         }
     740             : 
     741             :         return 0;
     742             : }
     743             : 
     744             : int
     745        1443 : _gnutls_write_new_general_name(ASN1_TYPE ext, const char *ext_name,
     746             :                        gnutls_x509_subject_alt_name_t type,
     747             :                        const void *data, unsigned int data_size)
     748             : {
     749        1443 :         int result;
     750        1443 :         char name[128];
     751             : 
     752        1443 :         result = asn1_write_value(ext, ext_name, "NEW", 1);
     753        1443 :         if (result != ASN1_SUCCESS) {
     754           0 :                 gnutls_assert();
     755           0 :                 return _gnutls_asn2err(result);
     756             :         }
     757             : 
     758        1443 :         if (ext_name[0] == 0) { /* no dot */
     759        1213 :                 _gnutls_str_cpy(name, sizeof(name), "?LAST");
     760             :         } else {
     761         230 :                 _gnutls_str_cpy(name, sizeof(name), ext_name);
     762         230 :                 _gnutls_str_cat(name, sizeof(name), ".?LAST");
     763             :         }
     764             : 
     765        1443 :         result = _gnutls_write_general_name(ext, name, type,
     766             :                 data, data_size);
     767        1443 :         if (result < 0) {
     768           0 :                 gnutls_assert();
     769           0 :                 return result;
     770             :         }
     771             : 
     772             :         return 0;
     773             : }
     774             : 
     775             : int
     776          63 : _gnutls_write_new_othername(ASN1_TYPE ext, const char *ext_name,
     777             :                        const char *oid,
     778             :                        const void *data, unsigned int data_size)
     779             : {
     780          63 :         int result;
     781          63 :         char name[128];
     782          63 :         char name2[128];
     783             : 
     784          63 :         result = asn1_write_value(ext, ext_name, "NEW", 1);
     785          63 :         if (result != ASN1_SUCCESS) {
     786           0 :                 gnutls_assert();
     787           0 :                 return _gnutls_asn2err(result);
     788             :         }
     789             : 
     790          63 :         if (ext_name[0] == 0) { /* no dot */
     791          63 :                 _gnutls_str_cpy(name, sizeof(name), "?LAST");
     792             :         } else {
     793           0 :                 _gnutls_str_cpy(name, sizeof(name), ext_name);
     794           0 :                 _gnutls_str_cat(name, sizeof(name), ".?LAST");
     795             :         }
     796             : 
     797          63 :         result = asn1_write_value(ext, name, "otherName", 1);
     798          63 :         if (result != ASN1_SUCCESS) {
     799           0 :                 gnutls_assert();
     800           0 :                 return _gnutls_asn2err(result);
     801             :         }
     802             : 
     803          63 :         snprintf(name2, sizeof(name2), "%s.otherName.type-id", name);
     804             : 
     805          63 :         result = asn1_write_value(ext, name2, oid, 1);
     806          63 :         if (result != ASN1_SUCCESS) {
     807           0 :                 gnutls_assert();
     808           0 :                 asn1_delete_structure(&ext);
     809           0 :                 return _gnutls_asn2err(result);
     810             :         }
     811             : 
     812          63 :         snprintf(name2, sizeof(name2), "%s.otherName.value", name);
     813             : 
     814          63 :         result = asn1_write_value(ext, name2, data, data_size);
     815          63 :         if (result != ASN1_SUCCESS) {
     816           0 :                 gnutls_assert();
     817           0 :                 asn1_delete_structure(&ext);
     818           0 :                 return _gnutls_asn2err(result);
     819             :         }
     820             : 
     821             :         return 0;
     822             : }
     823             : 
     824             : /* Convert the given name to GeneralNames in a DER encoded extension.
     825             :  * This is the same as subject alternative name.
     826             :  */
     827             : int
     828         376 : _gnutls_x509_ext_gen_subject_alt_name(gnutls_x509_subject_alt_name_t
     829             :                                       type,
     830             :                                       const char *othername_oid,
     831             :                                       const void *data,
     832             :                                       unsigned int data_size,
     833             :                                       const gnutls_datum_t * prev_der_ext,
     834             :                                       gnutls_datum_t * der_ext)
     835             : {
     836         376 :         int ret;
     837         376 :         gnutls_subject_alt_names_t sans = NULL;
     838         376 :         gnutls_datum_t name;
     839             : 
     840         376 :         ret = gnutls_subject_alt_names_init(&sans);
     841         376 :         if (ret < 0) {
     842           0 :                 gnutls_assert();
     843           0 :                 return ret;
     844             :         }
     845             : 
     846         376 :         if (prev_der_ext && prev_der_ext->data != NULL && 
     847         301 :                 prev_der_ext->size != 0) {
     848             : 
     849         301 :                 ret = gnutls_x509_ext_import_subject_alt_names(prev_der_ext, sans, 0);
     850         301 :                 if (ret < 0) {
     851           0 :                         gnutls_assert();
     852           0 :                         goto cleanup;
     853             :                 }
     854             :         }
     855             : 
     856         376 :         name.data = (void*)data;
     857         376 :         name.size = data_size;
     858         376 :         ret = gnutls_subject_alt_names_set(sans, type, &name, othername_oid);
     859         376 :         if (ret < 0) {
     860           3 :                 gnutls_assert();
     861           3 :                 goto cleanup;
     862             :         }
     863             : 
     864         373 :         ret = gnutls_x509_ext_export_subject_alt_names(sans, der_ext);
     865         373 :         if (ret < 0) {
     866           0 :                 gnutls_assert();
     867           0 :                 goto cleanup;
     868             :         }
     869             : 
     870             :         ret = 0;
     871         376 : cleanup:
     872         376 :         if (sans != NULL)
     873         376 :                 gnutls_subject_alt_names_deinit(sans);
     874             : 
     875             :         return ret;
     876             : }
     877             : 
     878             : /* generate the AuthorityKeyID in a DER encoded extension
     879             :  */
     880             : int
     881          47 : _gnutls_x509_ext_gen_auth_key_id(const void *id, size_t id_size,
     882             :                                  gnutls_datum_t * der_ext)
     883             : {
     884          47 :         gnutls_x509_aki_t aki;
     885          47 :         int ret;
     886          47 :         gnutls_datum_t l_id;
     887             : 
     888          47 :         ret = gnutls_x509_aki_init(&aki);
     889          47 :         if (ret < 0)
     890           0 :                 return gnutls_assert_val(ret);
     891             : 
     892          47 :         l_id.data = (void*)id;
     893          47 :         l_id.size = id_size;
     894          47 :         ret = gnutls_x509_aki_set_id(aki, &l_id);
     895          47 :         if (ret < 0) {
     896           0 :                 gnutls_assert();
     897           0 :                 goto cleanup;
     898             :         }
     899             : 
     900          47 :         ret = gnutls_x509_ext_export_authority_key_id(aki, der_ext);
     901          47 :         if (ret < 0) {
     902           0 :                 gnutls_assert();
     903           0 :                 goto cleanup;
     904             :         }
     905             : 
     906             :         ret = 0;
     907             : 
     908          47 :  cleanup:
     909          47 :         gnutls_x509_aki_deinit(aki);
     910          47 :         return ret;
     911             : }

Generated by: LCOV version 1.14