LCOV - code coverage report
Current view: top level - lib/util - asn1.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 470 634 74.1 %
Date: 2024-02-28 12:06:22 Functions: 52 56 92.9 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    simple ASN1 routines
       4             :    Copyright (C) Andrew Tridgell 2001
       5             : 
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include "replace.h"
      21             : #include "system/locale.h"
      22             : #include "lib/util/asn1.h"
      23             : #include "lib/util/debug.h"
      24             : #include "lib/util/samba_util.h"
      25             : #include "lib/util/smb_strtox.h"
      26             : 
      27             : struct nesting {
      28             :         off_t start;
      29             :         size_t taglen; /* for parsing */
      30             :         struct nesting *next;
      31             : };
      32             : 
      33             : 
      34             : struct asn1_data {
      35             :         uint8_t *data;
      36             :         size_t length;
      37             :         off_t ofs;
      38             :         struct nesting *nesting;
      39             :         bool has_error;
      40             :         unsigned depth;
      41             :         unsigned max_depth;
      42             : };
      43             : 
      44             : /* allocate an asn1 structure */
      45     5497473 : struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx, unsigned max_depth)
      46             : {
      47     5497473 :         struct asn1_data *ret = talloc_zero(mem_ctx, struct asn1_data);
      48     5497473 :         if (ret == NULL) {
      49           0 :                 DBG_ERR("asn1_init failed! out of memory\n");
      50           0 :                 return ret;
      51             :         }
      52     5497473 :         ret->max_depth = max_depth;
      53     5497473 :         return ret;
      54             : }
      55             : 
      56             : /* free an asn1 structure */
      57     4195485 : void asn1_free(struct asn1_data *data)
      58             : {
      59     4195485 :         talloc_free(data);
      60     4195485 : }
      61             : 
      62     4242254 : bool asn1_has_error(const struct asn1_data *data)
      63             : {
      64     4242254 :         return data->has_error;
      65             : }
      66             : 
      67         104 : void asn1_set_error(struct asn1_data *data)
      68             : {
      69         104 :         data->has_error = true;
      70         104 : }
      71             : 
      72     2028107 : bool asn1_has_nesting(const struct asn1_data *data)
      73             : {
      74     2028107 :         return data->nesting != NULL;
      75             : }
      76             : 
      77      567824 : off_t asn1_current_ofs(const struct asn1_data *data)
      78             : {
      79      567824 :         return data->ofs;
      80             : }
      81             : 
      82             : /* write to the ASN1 buffer, advancing the buffer pointer */
      83    93367014 : bool asn1_write(struct asn1_data *data, const void *p, int len)
      84             : {
      85    93367014 :         if (data->has_error) return false;
      86             : 
      87    93367014 :         if ((len < 0) || (data->ofs + (size_t)len < data->ofs)) {
      88           0 :                 data->has_error = true;
      89           0 :                 return false;
      90             :         }
      91             : 
      92    93367014 :         if (data->length < data->ofs+len) {
      93      206139 :                 uint8_t *newp;
      94    92038910 :                 newp = talloc_realloc(data, data->data, uint8_t, data->ofs+len);
      95    92038910 :                 if (!newp) {
      96           0 :                         data->has_error = true;
      97           0 :                         return false;
      98             :                 }
      99    92038910 :                 data->data = newp;
     100    92038910 :                 data->length = data->ofs+len;
     101             :         }
     102    93367014 :         if (len > 0) {
     103    92038910 :                 memcpy(data->data + data->ofs, p, len);
     104    92038910 :                 data->ofs += len;
     105             :         }
     106    93158841 :         return true;
     107             : }
     108             : 
     109             : /* useful fn for writing a uint8_t */
     110    79647739 : bool asn1_write_uint8(struct asn1_data *data, uint8_t v)
     111             : {
     112    79647739 :         return asn1_write(data, &v, 1);
     113             : }
     114             : 
     115             : /* push a tag onto the asn1 data buffer. Used for nested structures */
     116    34728184 : bool asn1_push_tag(struct asn1_data *data, uint8_t tag)
     117             : {
     118       75210 :         struct nesting *nesting;
     119             : 
     120    34728184 :         if (!asn1_write_uint8(data, tag)) {
     121           0 :                 return false;
     122             :         }
     123    34728184 :         nesting = talloc(data, struct nesting);
     124    34728184 :         if (!nesting) {
     125           0 :                 data->has_error = true;
     126           0 :                 return false;
     127             :         }
     128             : 
     129    34728184 :         nesting->start = data->ofs;
     130    34728184 :         nesting->next = data->nesting;
     131    34728184 :         data->nesting = nesting;
     132    34728184 :         return asn1_write_uint8(data, 0xff);
     133             : }
     134             : 
     135             : /* pop a tag */
     136    34728184 : bool asn1_pop_tag(struct asn1_data *data)
     137             : {
     138       75210 :         struct nesting *nesting;
     139       75210 :         size_t len;
     140             : 
     141    34728184 :         if (data->has_error) {
     142           0 :                 return false;
     143             :         }
     144             : 
     145    34728184 :         nesting = data->nesting;
     146             : 
     147    34728184 :         if (!nesting) {
     148           0 :                 data->has_error = true;
     149           0 :                 return false;
     150             :         }
     151    34728184 :         len = data->ofs - (nesting->start+1);
     152             :         /* yes, this is ugly. We don't know in advance how many bytes the length
     153             :            of a tag will take, so we assumed 1 byte. If we were wrong then we
     154             :            need to correct our mistake */
     155    34728184 :         if (len > 0xFFFFFF) {
     156           0 :                 data->data[nesting->start] = 0x84;
     157           0 :                 if (!asn1_write_uint8(data, 0)) return false;
     158           0 :                 if (!asn1_write_uint8(data, 0)) return false;
     159           0 :                 if (!asn1_write_uint8(data, 0)) return false;
     160           0 :                 if (!asn1_write_uint8(data, 0)) return false;
     161           0 :                 memmove(data->data+nesting->start+5, data->data+nesting->start+1, len);
     162           0 :                 data->data[nesting->start+1] = (len>>24) & 0xFF;
     163           0 :                 data->data[nesting->start+2] = (len>>16) & 0xFF;
     164           0 :                 data->data[nesting->start+3] = (len>>8) & 0xFF;
     165           0 :                 data->data[nesting->start+4] = len&0xff;
     166    34728184 :         } else if (len > 0xFFFF) {
     167       16735 :                 data->data[nesting->start] = 0x83;
     168       16735 :                 if (!asn1_write_uint8(data, 0)) return false;
     169       16735 :                 if (!asn1_write_uint8(data, 0)) return false;
     170       16735 :                 if (!asn1_write_uint8(data, 0)) return false;
     171       16735 :                 memmove(data->data+nesting->start+4, data->data+nesting->start+1, len);
     172       16735 :                 data->data[nesting->start+1] = (len>>16) & 0xFF;
     173       16735 :                 data->data[nesting->start+2] = (len>>8) & 0xFF;
     174       16735 :                 data->data[nesting->start+3] = len&0xff;
     175    34711449 :         } else if (len > 255) {
     176     1259723 :                 data->data[nesting->start] = 0x82;
     177     1259723 :                 if (!asn1_write_uint8(data, 0)) return false;
     178     1259723 :                 if (!asn1_write_uint8(data, 0)) return false;
     179     1259723 :                 memmove(data->data+nesting->start+3, data->data+nesting->start+1, len);
     180     1259723 :                 data->data[nesting->start+1] = len>>8;
     181     1259723 :                 data->data[nesting->start+2] = len&0xff;
     182    33451726 :         } else if (len > 127) {
     183     1388446 :                 data->data[nesting->start] = 0x81;
     184     1388446 :                 if (!asn1_write_uint8(data, 0)) return false;
     185     1388446 :                 memmove(data->data+nesting->start+2, data->data+nesting->start+1, len);
     186     1388446 :                 data->data[nesting->start+1] = len;
     187             :         } else {
     188    32063280 :                 data->data[nesting->start] = len;
     189             :         }
     190             : 
     191    34728184 :         data->nesting = nesting->next;
     192    34728184 :         talloc_free(nesting);
     193    34728184 :         return true;
     194             : }
     195             : 
     196             : /* "i" is the one's complement representation, as is the normal result of an
     197             :  * implicit signed->unsigned conversion */
     198             : 
     199     3876007 : static bool push_int_bigendian(struct asn1_data *data, unsigned int i, bool negative)
     200             : {
     201     3876007 :         uint8_t lowest = i & 0xFF;
     202             : 
     203     3876007 :         i = i >> 8;
     204     3876007 :         if (i != 0)
     205      631392 :                 if (!push_int_bigendian(data, i, negative))
     206           0 :                         return false;
     207             : 
     208     3876007 :         if (data->nesting->start+1 == data->ofs) {
     209             : 
     210             :                 /* We did not write anything yet, looking at the highest
     211             :                  * valued byte */
     212             : 
     213     3244624 :                 if (negative) {
     214             :                         /* Don't write leading 0xff's */
     215          18 :                         if (lowest == 0xFF)
     216           0 :                                 return true;
     217             : 
     218           9 :                         if ((lowest & 0x80) == 0) {
     219             :                                 /* The only exception for a leading 0xff is if
     220             :                                  * the highest bit is 0, which would indicate
     221             :                                  * a positive value */
     222           2 :                                 if (!asn1_write_uint8(data, 0xff))
     223           0 :                                         return false;
     224             :                         }
     225             :                 } else {
     226     3244606 :                         if (lowest & 0x80) {
     227             :                                 /* The highest bit of a positive integer is 1,
     228             :                                  * this would indicate a negative number. Push
     229             :                                  * a 0 to indicate a positive one */
     230       69081 :                                 if (!asn1_write_uint8(data, 0))
     231           0 :                                         return false;
     232             :                         }
     233             :                 }
     234             :         }
     235             : 
     236     3875998 :         return asn1_write_uint8(data, lowest);
     237             : }
     238             : 
     239             : /* write an Integer without the tag framing. Needed for example for the LDAP
     240             :  * Abandon Operation */
     241             : 
     242     3244616 : bool asn1_write_implicit_Integer(struct asn1_data *data, int i)
     243             : {
     244     3244616 :         if (data->has_error) {
     245           0 :                 return false;
     246             :         }
     247             : 
     248     3244616 :         if (i == -1) {
     249             :                 /* -1 is special as it consists of all-0xff bytes. In
     250             :                     push_int_bigendian this is the only case that is not
     251             :                     properly handled, as all 0xff bytes would be handled as
     252             :                     leading ones to be ignored. */
     253           1 :                 return asn1_write_uint8(data, 0xff);
     254             :         } else {
     255     3244615 :                 return push_int_bigendian(data, i, i<0);
     256             :         }
     257             : }
     258             : 
     259             : 
     260             : /* write an integer */
     261     3244536 : bool asn1_write_Integer(struct asn1_data *data, int i)
     262             : {
     263     3244536 :         if (!asn1_push_tag(data, ASN1_INTEGER)) return false;
     264     3244536 :         if (!asn1_write_implicit_Integer(data, i)) return false;
     265     3244536 :         return asn1_pop_tag(data);
     266             : }
     267             : 
     268             : /* write a BIT STRING */
     269           0 : bool asn1_write_BitString(struct asn1_data *data, const void *p, size_t length, uint8_t padding)
     270             : {
     271           0 :         if (!asn1_push_tag(data, ASN1_BIT_STRING)) return false;
     272           0 :         if (!asn1_write_uint8(data, padding)) return false;
     273           0 :         if (!asn1_write(data, p, length)) return false;
     274           0 :         return asn1_pop_tag(data);
     275             : }
     276             : 
     277    99435607 : bool ber_write_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *OID)
     278             : {
     279     1294015 :         unsigned int v, v2;
     280    99435607 :         const char *p = (const char *)OID;
     281     1294015 :         char *newp;
     282     1294015 :         int i;
     283    99435607 :         int error = 0;
     284             : 
     285    99435607 :         if (!isdigit(*p)) return false;
     286    99435605 :         v = smb_strtoul(p, &newp, 10, &error, SMB_STR_STANDARD);
     287    99435605 :         if (newp[0] != '.' || error != 0) {
     288           0 :                 return false;
     289             :         }
     290    99435605 :         p = newp + 1;
     291             : 
     292    99435605 :         if (!isdigit(*p)) return false;
     293    99435603 :         v2 = smb_strtoul(p, &newp, 10, &error, SMB_STR_STANDARD);
     294    99435603 :         if (newp[0] != '.' || error != 0) {
     295           0 :                 return false;
     296             :         }
     297    99435602 :         p = newp + 1;
     298             : 
     299             :         /*the ber representation can't use more space than the string one */
     300    99435602 :         *blob = data_blob_talloc(mem_ctx, NULL, strlen(OID));
     301    99435602 :         if (!blob->data) return false;
     302             : 
     303    99435602 :         blob->data[0] = 40*v + v2;
     304             : 
     305    99435602 :         i = 1;
     306   479425159 :         while (*p) {
     307   379989559 :                 if (!isdigit(*p)) return false;
     308   379989558 :                 v = smb_strtoul(p, &newp, 10, &error, SMB_STR_STANDARD);
     309   379989558 :                 if (newp[0] == '.' || error != 0) {
     310   280553958 :                         p = newp + 1;
     311             :                         /* check for empty last component */
     312   280553958 :                         if (!*p) return false;
     313    99435600 :                 } else if (newp[0] == '\0') {
     314    98141592 :                         p = newp;
     315             :                 } else {
     316           0 :                         data_blob_free(blob);
     317           0 :                         return false;
     318             :                 }
     319   379989557 :                 if (v >= (1<<28)) blob->data[i++] = (0x80 | ((v>>28)&0x7f));
     320   379989557 :                 if (v >= (1<<21)) blob->data[i++] = (0x80 | ((v>>21)&0x7f));
     321   379989557 :                 if (v >= (1<<14)) blob->data[i++] = (0x80 | ((v>>14)&0x7f));
     322   379989557 :                 if (v >= (1<<7)) blob->data[i++] = (0x80 | ((v>>7)&0x7f));
     323   379989557 :                 blob->data[i++] = (v&0x7f);
     324             :         }
     325             : 
     326    99435600 :         blob->length = i;
     327             : 
     328    99435600 :         return true;
     329             : }
     330             : 
     331             : /**
     332             :  * Serialize partial OID string.
     333             :  * Partial OIDs are in the form:
     334             :  *   1:2.5.6:0x81
     335             :  *   1:2.5.6:0x8182
     336             :  */
     337       13078 : bool ber_write_partial_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *partial_oid)
     338             : {
     339       13078 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     340       13078 :         char *oid = talloc_strdup(tmp_ctx, partial_oid);
     341        1065 :         char *p;
     342             : 
     343             :         /* truncate partial part so ber_write_OID_String() works */
     344       13078 :         p = strchr(oid, ':');
     345       13078 :         if (p) {
     346           6 :                 *p = '\0';
     347           6 :                 p++;
     348             :         }
     349             : 
     350       13078 :         if (!ber_write_OID_String(mem_ctx, blob, oid)) {
     351           0 :                 talloc_free(tmp_ctx);
     352           0 :                 return false;
     353             :         }
     354             : 
     355             :         /* Add partially encoded sub-identifier */
     356       13078 :         if (p) {
     357           6 :                 DATA_BLOB tmp_blob = strhex_to_data_blob(tmp_ctx, p);
     358           6 :                 if (!data_blob_append(mem_ctx, blob, tmp_blob.data,
     359             :                                       tmp_blob.length)) {
     360           0 :                         talloc_free(tmp_ctx);
     361           0 :                         return false;
     362             :                 }
     363             :         }
     364             : 
     365       13078 :         talloc_free(tmp_ctx);
     366             : 
     367       13078 :         return true;
     368             : }
     369             : 
     370             : /* write an object ID to a ASN1 buffer */
     371      795507 : bool asn1_write_OID(struct asn1_data *data, const char *OID)
     372             : {
     373       20166 :         DATA_BLOB blob;
     374             : 
     375      795507 :         if (!asn1_push_tag(data, ASN1_OID)) return false;
     376             : 
     377      795507 :         if (!ber_write_OID_String(NULL, &blob, OID)) {
     378           0 :                 data->has_error = true;
     379           0 :                 return false;
     380             :         }
     381             : 
     382      795507 :         if (!asn1_write(data, blob.data, blob.length)) {
     383           0 :                 data_blob_free(&blob);
     384           0 :                 data->has_error = true;
     385           0 :                 return false;
     386             :         }
     387      795507 :         data_blob_free(&blob);
     388      795507 :         return asn1_pop_tag(data);
     389             : }
     390             : 
     391             : /* write an octet string */
     392    12154874 : bool asn1_write_OctetString(struct asn1_data *data, const void *p, size_t length)
     393             : {
     394    12154874 :         if (!asn1_push_tag(data, ASN1_OCTET_STRING)) return false;
     395    12154874 :         if (!asn1_write(data, p, length)) return false;
     396    12154874 :         return asn1_pop_tag(data);
     397             : }
     398             : 
     399             : /* write a LDAP string */
     400      542461 : bool asn1_write_LDAPString(struct asn1_data *data, const char *s)
     401             : {
     402      542461 :         return asn1_write(data, s, strlen(s));
     403             : }
     404             : 
     405             : /* write a LDAP string from a DATA_BLOB */
     406       32761 : bool asn1_write_DATA_BLOB_LDAPString(struct asn1_data *data, const DATA_BLOB *s)
     407             : {
     408       32761 :         return asn1_write(data, s->data, s->length);
     409             : }
     410             : 
     411             : /* write a general string */
     412           0 : bool asn1_write_GeneralString(struct asn1_data *data, const char *s)
     413             : {
     414           0 :         if (!asn1_push_tag(data, ASN1_GENERAL_STRING)) return false;
     415           0 :         if (!asn1_write_LDAPString(data, s)) return false;
     416           0 :         return asn1_pop_tag(data);
     417             : }
     418             : 
     419       35568 : bool asn1_write_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob)
     420             : {
     421       35568 :         if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(num))) return false;
     422       35568 :         if (!asn1_write(data, blob->data, blob->length)) return false;
     423       35568 :         return asn1_pop_tag(data);
     424             : }
     425             : 
     426             : /* write a BOOLEAN */
     427      628615 : bool asn1_write_BOOLEAN(struct asn1_data *data, bool v)
     428             : {
     429      628615 :         if (!asn1_push_tag(data, ASN1_BOOLEAN)) return false;
     430      629022 :         if (!asn1_write_uint8(data, v ? 0xFF : 0)) return false;
     431      628615 :         return asn1_pop_tag(data);
     432             : }
     433             : 
     434      631437 : bool asn1_read_BOOLEAN(struct asn1_data *data, bool *v)
     435             : {
     436      631437 :         uint8_t tmp = 0;
     437      631437 :         if (!asn1_start_tag(data, ASN1_BOOLEAN)) return false;
     438      631437 :         *v = false;
     439      631437 :         if (!asn1_read_uint8(data, &tmp)) return false;
     440      631437 :         if (tmp == 0xFF) {
     441      264267 :                 *v = true;
     442             :         }
     443      631437 :         return asn1_end_tag(data);
     444             : }
     445             : 
     446             : /* write a BOOLEAN in a simple context */
     447          21 : bool asn1_write_BOOLEAN_context(struct asn1_data *data, bool v, int context)
     448             : {
     449          21 :         if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(context))) return false;
     450          21 :         if (!asn1_write_uint8(data, v ? 0xFF : 0)) return false;
     451          21 :         return asn1_pop_tag(data);
     452             : }
     453             : 
     454          21 : bool asn1_read_BOOLEAN_context(struct asn1_data *data, bool *v, int context)
     455             : {
     456          21 :         uint8_t tmp = 0;
     457          21 :         if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(context))) return false;
     458          21 :         *v = false;
     459          21 :         if (!asn1_read_uint8(data, &tmp)) return false;
     460          21 :         if (tmp == 0xFF) {
     461          21 :                 *v = true;
     462             :         }
     463          21 :         return asn1_end_tag(data);
     464             : }
     465             : 
     466             : /* check a BOOLEAN */
     467           0 : bool asn1_check_BOOLEAN(struct asn1_data *data, bool v)
     468             : {
     469           0 :         uint8_t b = 0;
     470             : 
     471           0 :         if (!asn1_read_uint8(data, &b)) return false;
     472           0 :         if (b != ASN1_BOOLEAN) {
     473           0 :                 data->has_error = true;
     474           0 :                 return false;
     475             :         }
     476           0 :         if (!asn1_read_uint8(data, &b)) return false;
     477           0 :         if (b != v) {
     478           0 :                 data->has_error = true;
     479           0 :                 return false;
     480             :         }
     481           0 :         return !data->has_error;
     482             : }
     483             : 
     484             : 
     485             : /* load a struct asn1_data structure with a lump of data, ready to be parsed */
     486      608395 : bool asn1_load(struct asn1_data *data, DATA_BLOB blob)
     487             : {
     488             :         /*
     489             :          * Save the maximum depth
     490             :          */
     491      608395 :         unsigned max_depth = data->max_depth;
     492             : 
     493      608395 :         ZERO_STRUCTP(data);
     494      608395 :         data->data = (uint8_t *)talloc_memdup(data, blob.data, blob.length);
     495      608395 :         if (!data->data) {
     496           0 :                 data->has_error = true;
     497           0 :                 return false;
     498             :         }
     499      608395 :         data->length = blob.length;
     500      608395 :         data->max_depth = max_depth;
     501      608395 :         return true;
     502             : }
     503             : 
     504             : /* Peek into an ASN1 buffer, not advancing the pointer */
     505   115631412 : bool asn1_peek(struct asn1_data *data, void *p, int len)
     506             : {
     507   115631412 :         if (data->has_error)
     508           0 :                 return false;
     509             : 
     510   115631412 :         if (len < 0 || data->ofs + len < data->ofs || data->ofs + len < len)
     511           0 :                 return false;
     512             : 
     513   115631412 :         if (data->ofs + len > data->length) {
     514             :                 /* we need to mark the buffer as consumed, so the caller knows
     515             :                    this was an out of data error, and not a decode error */
     516      182501 :                 data->ofs = data->length;
     517      182501 :                 return false;
     518             :         }
     519             : 
     520   115448911 :         memcpy(p, data->data + data->ofs, len);
     521   115448911 :         return true;
     522             : }
     523             : 
     524             : /* read from a ASN1 buffer, advancing the buffer pointer */
     525   102681000 : bool asn1_read(struct asn1_data *data, void *p, int len)
     526             : {
     527   102681000 :         if (!asn1_peek(data, p, len)) {
     528      182501 :                 data->has_error = true;
     529      182501 :                 return false;
     530             :         }
     531             : 
     532   102498499 :         data->ofs += len;
     533   102498499 :         return true;
     534             : }
     535             : 
     536             : /* read a uint8_t from a ASN1 buffer */
     537    89390742 : bool asn1_read_uint8(struct asn1_data *data, uint8_t *v)
     538             : {
     539    89390742 :         return asn1_read(data, v, 1);
     540             : }
     541             : 
     542    12950412 : bool asn1_peek_uint8(struct asn1_data *data, uint8_t *v)
     543             : {
     544    12950412 :         return asn1_peek(data, v, 1);
     545             : }
     546             : 
     547    15899090 : bool asn1_peek_tag(struct asn1_data *data, uint8_t tag)
     548             : {
     549        7604 :         uint8_t b;
     550             : 
     551    15899090 :         if (asn1_tag_remaining(data) <= 0) {
     552     6932297 :                 return false;
     553             :         }
     554             : 
     555     8962451 :         if (!asn1_peek_uint8(data, &b))
     556           0 :                 return false;
     557             : 
     558     8962451 :         return (b == tag);
     559             : }
     560             : 
     561             : /*
     562             :  * just get the needed size the tag would consume
     563             :  */
     564     4655062 : static bool asn1_peek_tag_needed_size(struct asn1_data *data, uint8_t tag,
     565             :                                       size_t *size)
     566             : {
     567     4655062 :         off_t start_ofs = data->ofs;
     568       11798 :         uint8_t b;
     569     4655062 :         size_t taglen = 0;
     570             : 
     571     4655062 :         if (data->has_error) {
     572           0 :                 return false;
     573             :         }
     574             : 
     575     4655062 :         if (!asn1_read_uint8(data, &b)) {
     576      182500 :                 data->ofs = start_ofs;
     577      182500 :                 data->has_error = false;
     578      182500 :                 return false;
     579             :         }
     580             : 
     581     4472562 :         if (b != tag) {
     582      159513 :                 data->ofs = start_ofs;
     583      159513 :                 data->has_error = false;
     584      159513 :                 return false;
     585             :         }
     586             : 
     587     4313049 :         if (!asn1_read_uint8(data, &b)) {
     588           0 :                 data->ofs = start_ofs;
     589           0 :                 data->has_error = false;
     590           0 :                 return false;
     591             :         }
     592             : 
     593     4313049 :         if (b & 0x80) {
     594     1670671 :                 int n = b & 0x7f;
     595     1670671 :                 if (!asn1_read_uint8(data, &b)) {
     596           0 :                         data->ofs = start_ofs;
     597           0 :                         data->has_error = false;
     598           0 :                         return false;
     599             :                 }
     600     1670671 :                 if (n > 4) {
     601             :                         /*
     602             :                          * We should not allow more than 4 bytes
     603             :                          * for the encoding of the tag length.
     604             :                          *
     605             :                          * Otherwise we'd overflow the taglen
     606             :                          * variable on 32 bit systems.
     607             :                          */
     608           0 :                         data->ofs = start_ofs;
     609           0 :                         data->has_error = false;
     610           0 :                         return false;
     611             :                 }
     612     1670671 :                 taglen = b;
     613     2321332 :                 while (n > 1) {
     614        1749 :                         size_t tmp_taglen;
     615             : 
     616      650661 :                         if (!asn1_read_uint8(data, &b)) {
     617           0 :                                 data->ofs = start_ofs;
     618           0 :                                 data->has_error = false;
     619           0 :                                 return false;
     620             :                         }
     621             : 
     622      650661 :                         tmp_taglen = (taglen << 8) | b;
     623             : 
     624      650661 :                         if ((tmp_taglen >> 8) != taglen) {
     625             :                                 /* overflow */
     626           0 :                                 data->ofs = start_ofs;
     627           0 :                                 data->has_error = false;
     628           0 :                                 return false;
     629             :                         }
     630      650661 :                         taglen = tmp_taglen;
     631             : 
     632      650661 :                         n--;
     633             :                 }
     634             :         } else {
     635     2642378 :                 taglen = b;
     636             :         }
     637             : 
     638     4313049 :         *size = (data->ofs - start_ofs) + taglen;
     639             : 
     640     4313049 :         data->ofs = start_ofs;
     641     4313049 :         data->has_error = false;
     642     4313049 :         return true;
     643             : }
     644             : 
     645             : /* start reading a nested asn1 structure */
     646    33951283 : bool asn1_start_tag(struct asn1_data *data, uint8_t tag)
     647             : {
     648       57772 :         uint8_t b;
     649       57772 :         struct nesting *nesting;
     650             : 
     651             :         /*
     652             :          * Check the depth of the parse tree and prevent it from growing
     653             :          * too large.
     654             :          */
     655    33951283 :         data->depth++;
     656    33951283 :         if (data->depth > data->max_depth) {
     657           2 :                 data->has_error = true;
     658           2 :                 return false;
     659             :         }
     660             : 
     661    33951281 :         if (!asn1_read_uint8(data, &b))
     662           0 :                 return false;
     663             : 
     664    33951280 :         if (b != tag) {
     665          38 :                 data->has_error = true;
     666          38 :                 return false;
     667             :         }
     668    33951242 :         nesting = talloc(data, struct nesting);
     669    33951242 :         if (!nesting) {
     670           0 :                 data->has_error = true;
     671           0 :                 return false;
     672             :         }
     673             : 
     674    33951242 :         if (!asn1_read_uint8(data, &b)) {
     675           0 :                 return false;
     676             :         }
     677             : 
     678    33951242 :         if (b & 0x80) {
     679     2664768 :                 int n = b & 0x7f;
     680     2664768 :                 if (!asn1_read_uint8(data, &b))
     681           0 :                         return false;
     682     2664768 :                 nesting->taglen = b;
     683     3955107 :                 while (n > 1) {
     684        6582 :                         size_t taglen;
     685             : 
     686     1290339 :                         if (!asn1_read_uint8(data, &b))
     687           0 :                                 return false;
     688             : 
     689     1290339 :                         taglen = (nesting->taglen << 8) | b;
     690             : 
     691     1290339 :                         if ((taglen >> 8) != nesting->taglen) {
     692             :                                 /* overflow */
     693           0 :                                 data->has_error = true;
     694           0 :                                 return false;
     695             :                         }
     696     1290339 :                         nesting->taglen = taglen;
     697             : 
     698     1290339 :                         n--;
     699             :                 }
     700             :         } else {
     701    31286474 :                 nesting->taglen = b;
     702             :         }
     703    33951242 :         nesting->start = data->ofs;
     704    33951242 :         nesting->next = data->nesting;
     705    33951242 :         data->nesting = nesting;
     706    33951242 :         if (asn1_tag_remaining(data) == -1) {
     707           0 :                 return false;
     708             :         }
     709    33951242 :         return !data->has_error;
     710             : }
     711             : 
     712             : /* stop reading a tag */
     713    33949553 : bool asn1_end_tag(struct asn1_data *data)
     714             : {
     715       57254 :         struct nesting *nesting;
     716             : 
     717    33949553 :         if (data->depth == 0) {
     718           0 :                 smb_panic("Unbalanced ASN.1 Tag nesting");
     719             :         }
     720    33949553 :         data->depth--;
     721             :         /* make sure we read it all */
     722    33949553 :         if (asn1_tag_remaining(data) != 0) {
     723           2 :                 data->has_error = true;
     724           2 :                 return false;
     725             :         }
     726             : 
     727    33949551 :         nesting = data->nesting;
     728             : 
     729    33949551 :         if (!nesting) {
     730           0 :                 data->has_error = true;
     731           0 :                 return false;
     732             :         }
     733             : 
     734    33949551 :         data->nesting = nesting->next;
     735    33949551 :         talloc_free(nesting);
     736    33949551 :         return true;
     737             : }
     738             : 
     739             : /* work out how many bytes are left in this nested tag */
     740   110698430 : int asn1_tag_remaining(struct asn1_data *data)
     741             : {
     742      176099 :         int remaining;
     743   110698430 :         if (data->has_error) {
     744           0 :                 return -1;
     745             :         }
     746             : 
     747   110698430 :         if (!data->nesting) {
     748           0 :                 data->has_error = true;
     749           0 :                 return -1;
     750             :         }
     751   110698430 :         remaining = data->nesting->taglen - (data->ofs - data->nesting->start);
     752   110698430 :         if (remaining > (data->length - data->ofs)) {
     753           0 :                 data->has_error = true;
     754           0 :                 return -1;
     755             :         }
     756   110698430 :         if (remaining < 0) {
     757           0 :                 data->has_error = true;
     758           0 :                 return -1;
     759             :         }
     760   110522331 :         return remaining;
     761             : }
     762             : 
     763             : /**
     764             :  * Internal implementation for reading binary OIDs
     765             :  * Reading is done as far in the buffer as valid OID
     766             :  * till buffer ends or not valid sub-identifier is found.
     767             :  */
     768    13933213 : static bool _ber_read_OID_String_impl(TALLOC_CTX *mem_ctx, DATA_BLOB blob,
     769             :                                       char **OID, size_t *bytes_eaten)
     770             : {
     771      180611 :         int i;
     772      180611 :         uint8_t *b;
     773      180611 :         unsigned int v;
     774    13933213 :         char *tmp_oid = NULL;
     775             : 
     776    13933213 :         if (blob.length < 2) return false;
     777             : 
     778    13933213 :         b = blob.data;
     779             : 
     780    13933213 :         tmp_oid = talloc_asprintf(mem_ctx, "%u.%u", b[0]/40, b[0]%40);
     781    13933213 :         if (!tmp_oid) goto nomem;
     782             : 
     783    13933213 :         if (bytes_eaten != NULL) {
     784    13933213 :                 *bytes_eaten = 0;
     785             :         }
     786             : 
     787   119056171 :         for(i = 1, v = 0; i < blob.length; i++) {
     788   105122958 :                 v = (v<<7) | (b[i]&0x7f);
     789   105122958 :                 if ( ! (b[i] & 0x80)) {
     790    63782727 :                         tmp_oid = talloc_asprintf_append_buffer(tmp_oid, ".%u",  v);
     791    63782727 :                         v = 0;
     792    63782727 :                         if (bytes_eaten)
     793    63782727 :                                 *bytes_eaten = i+1;
     794             :                 }
     795   105122958 :                 if (!tmp_oid) goto nomem;
     796             :         }
     797             : 
     798    13933213 :         *OID = tmp_oid;
     799    13933213 :         return true;
     800             : 
     801           0 : nomem:
     802           0 :         return false;
     803             : }
     804             : 
     805             : /* read an object ID from a data blob */
     806    13931170 : bool ber_read_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, char **OID)
     807             : {
     808      180431 :         size_t bytes_eaten;
     809             : 
     810    13931170 :         if (!_ber_read_OID_String_impl(mem_ctx, blob, OID, &bytes_eaten))
     811           0 :                 return false;
     812             : 
     813    13931170 :         return (bytes_eaten == blob.length);
     814             : }
     815             : 
     816             : /**
     817             :  * Deserialize partial OID string.
     818             :  * Partial OIDs are in the form:
     819             :  *   1:2.5.6:0x81
     820             :  *   1:2.5.6:0x8182
     821             :  */
     822        2043 : bool ber_read_partial_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob,
     823             :                                  char **partial_oid)
     824             : {
     825         180 :         size_t bytes_left;
     826         180 :         size_t bytes_eaten;
     827        2043 :         char *identifier = NULL;
     828        2043 :         char *tmp_oid = NULL;
     829             : 
     830        2043 :         if (!_ber_read_OID_String_impl(mem_ctx, blob, &tmp_oid, &bytes_eaten))
     831           0 :                 return false;
     832             : 
     833        2043 :         if (bytes_eaten < blob.length) {
     834           6 :                 bytes_left = blob.length - bytes_eaten;
     835           6 :                 identifier = hex_encode_talloc(mem_ctx, &blob.data[bytes_eaten], bytes_left);
     836           6 :                 if (!identifier)        goto nomem;
     837             : 
     838           6 :                 *partial_oid = talloc_asprintf_append_buffer(tmp_oid, ":0x%s", identifier);
     839           6 :                 if (!*partial_oid)      goto nomem;
     840           6 :                 TALLOC_FREE(identifier);
     841             :         } else {
     842        2037 :                 *partial_oid = tmp_oid;
     843             :         }
     844             : 
     845        1863 :         return true;
     846             : 
     847           0 : nomem:
     848           0 :         TALLOC_FREE(identifier);
     849           0 :         TALLOC_FREE(tmp_oid);
     850           0 :         return false;
     851             : }
     852             : 
     853             : /* read an object ID from a ASN1 buffer */
     854      391562 : bool asn1_read_OID(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **OID)
     855             : {
     856        9135 :         DATA_BLOB blob;
     857        9135 :         int len;
     858             : 
     859      391562 :         if (!asn1_start_tag(data, ASN1_OID)) return false;
     860             : 
     861      391562 :         len = asn1_tag_remaining(data);
     862      391562 :         if (len < 0) {
     863           0 :                 data->has_error = true;
     864           0 :                 return false;
     865             :         }
     866             : 
     867      391562 :         blob = data_blob(NULL, len);
     868      391562 :         if (!blob.data) {
     869           0 :                 data->has_error = true;
     870           0 :                 return false;
     871             :         }
     872             : 
     873      391562 :         if (!asn1_read(data, blob.data, len)) return false;
     874      391562 :         if (!asn1_end_tag(data)) {
     875           0 :                 data_blob_free(&blob);
     876           0 :                 return false;
     877             :         }
     878             : 
     879      391562 :         if (!ber_read_OID_String(mem_ctx, blob, OID)) {
     880           0 :                 data->has_error = true;
     881           0 :                 data_blob_free(&blob);
     882           0 :                 return false;
     883             :         }
     884             : 
     885      391562 :         data_blob_free(&blob);
     886      391562 :         return true;
     887             : }
     888             : 
     889             : /* check that the next object ID is correct */
     890      115870 : bool asn1_check_OID(struct asn1_data *data, const char *OID)
     891             : {
     892        2136 :         char *id;
     893             : 
     894      115870 :         if (!asn1_read_OID(data, data, &id)) return false;
     895             : 
     896      115870 :         if (strcmp(id, OID) != 0) {
     897          45 :                 talloc_free(id);
     898          45 :                 data->has_error = true;
     899          45 :                 return false;
     900             :         }
     901      115825 :         talloc_free(id);
     902      115825 :         return true;
     903             : }
     904             : 
     905             : /* read a LDAPString from a ASN1 buffer */
     906      619851 : bool asn1_read_LDAPString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s)
     907             : {
     908        1703 :         int len;
     909      619851 :         len = asn1_tag_remaining(data);
     910      619851 :         if (len < 0) {
     911           0 :                 data->has_error = true;
     912           0 :                 return false;
     913             :         }
     914      619851 :         *s = talloc_array(mem_ctx, char, len+1);
     915      619851 :         if (! *s) {
     916           0 :                 data->has_error = true;
     917           0 :                 return false;
     918             :         }
     919      619851 :         (*s)[len] = 0;
     920      619851 :         return asn1_read(data, *s, len);
     921             : }
     922             : 
     923             : 
     924             : /* read a GeneralString from a ASN1 buffer */
     925       42830 : bool asn1_read_GeneralString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s)
     926             : {
     927       42830 :         if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return false;
     928       42830 :         if (!asn1_read_LDAPString(data, mem_ctx, s)) return false;
     929       42830 :         return asn1_end_tag(data);
     930             : }
     931             : 
     932             : 
     933             : /* read a octet string blob */
     934    12145263 : bool asn1_read_OctetString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob)
     935             : {
     936        9684 :         int len;
     937    12145263 :         ZERO_STRUCTP(blob);
     938    12145263 :         if (!asn1_start_tag(data, ASN1_OCTET_STRING)) return false;
     939    12145263 :         len = asn1_tag_remaining(data);
     940    12145263 :         if (len < 0) {
     941           0 :                 data->has_error = true;
     942           0 :                 return false;
     943             :         }
     944    12145263 :         *blob = data_blob_talloc(mem_ctx, NULL, len+1);
     945    12145263 :         if (!blob->data || blob->length < len) {
     946           0 :                 data->has_error = true;
     947           0 :                 return false;
     948             :         }
     949    12145263 :         if (!asn1_read(data, blob->data, len)) goto err;
     950    12145263 :         if (!asn1_end_tag(data)) goto err;
     951    12145263 :         blob->length--;
     952    12145263 :         blob->data[len] = 0;
     953    12145263 :         return true;
     954             : 
     955           0 :   err:
     956             : 
     957           0 :         data_blob_free(blob);
     958           0 :         *blob = data_blob_null;
     959           0 :         return false;
     960             : }
     961             : 
     962       58022 : bool asn1_read_ContextSimple(struct asn1_data *data, TALLOC_CTX *mem_ctx, uint8_t num,
     963             :                              DATA_BLOB *blob)
     964             : {
     965         123 :         int len;
     966       58022 :         ZERO_STRUCTP(blob);
     967       58022 :         if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(num))) return false;
     968       58022 :         len = asn1_tag_remaining(data);
     969       58022 :         if (len < 0) {
     970           0 :                 data->has_error = true;
     971           0 :                 return false;
     972             :         }
     973       58022 :         *blob = data_blob_talloc(mem_ctx, NULL, len + 1);
     974       58022 :         if ((len != 0) && (!blob->data)) {
     975           0 :                 data->has_error = true;
     976           0 :                 return false;
     977             :         }
     978       58022 :         if (!asn1_read(data, blob->data, len)) return false;
     979       58022 :         blob->length--;
     980       58022 :         blob->data[len] = 0;
     981       58022 :         return asn1_end_tag(data);
     982             : }
     983             : 
     984             : /* read an integer without tag*/
     985     3247415 : bool asn1_read_implicit_Integer(struct asn1_data *data, int *i)
     986             : {
     987        2926 :         uint8_t b;
     988     3247415 :         uint32_t x = 0;
     989     3247415 :         bool first_byte = true;
     990             : 
     991     3247415 :         *i = 0;
     992             : 
     993     7198364 :         while (!data->has_error && asn1_tag_remaining(data)>0) {
     994     3950949 :                 if (!asn1_read_uint8(data, &b)) return false;
     995     3950949 :                 if (first_byte) {
     996     3247415 :                         if (b & 0x80) {
     997             :                                 /* Number is negative. */
     998          10 :                                 x = (uint32_t)-1;
     999             :                         }
    1000     3244489 :                         first_byte = false;
    1001             :                 }
    1002     3950949 :                 x = (x << 8) + b;
    1003             :         }
    1004     3247415 :         *i = (int)x;
    1005             : 
    1006     3247415 :         return !data->has_error;
    1007             : }
    1008             : 
    1009             : /* read an integer */
    1010     3247335 : bool asn1_read_Integer(struct asn1_data *data, int *i)
    1011             : {
    1012     3247335 :         *i = 0;
    1013             : 
    1014     3247335 :         if (!asn1_start_tag(data, ASN1_INTEGER)) return false;
    1015     3247335 :         if (!asn1_read_implicit_Integer(data, i)) return false;
    1016     3247335 :         return asn1_end_tag(data);
    1017             : }
    1018             : 
    1019             : /* read a BIT STRING */
    1020           0 : bool asn1_read_BitString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob, uint8_t *padding)
    1021             : {
    1022           0 :         int len;
    1023           0 :         ZERO_STRUCTP(blob);
    1024           0 :         if (!asn1_start_tag(data, ASN1_BIT_STRING)) return false;
    1025           0 :         len = asn1_tag_remaining(data);
    1026           0 :         if (len < 0) {
    1027           0 :                 data->has_error = true;
    1028           0 :                 return false;
    1029             :         }
    1030           0 :         if (!asn1_read_uint8(data, padding)) return false;
    1031             : 
    1032           0 :         *blob = data_blob_talloc(mem_ctx, NULL, len+1);
    1033           0 :         if (!blob->data || blob->length < len) {
    1034           0 :                 data->has_error = true;
    1035           0 :                 return false;
    1036             :         }
    1037           0 :         if (asn1_read(data, blob->data, len - 1)) {
    1038           0 :                 blob->length--;
    1039           0 :                 blob->data[len] = 0;
    1040           0 :                 asn1_end_tag(data);
    1041             :         }
    1042             : 
    1043           0 :         if (data->has_error) {
    1044           0 :                 data_blob_free(blob);
    1045           0 :                 *blob = data_blob_null;
    1046           0 :                 *padding = 0;
    1047           0 :                 return false;
    1048             :         }
    1049           0 :         return true;
    1050             : }
    1051             : 
    1052             : /* read a non-negative enumerated value */
    1053     1529412 : bool asn1_read_enumerated(struct asn1_data *data, int *v)
    1054             : {
    1055     1529412 :         unsigned int val_will_wrap = (0xFFU << ((sizeof(int)*8)-8));
    1056     1529412 :         *v = 0;
    1057             : 
    1058     1529412 :         if (!asn1_start_tag(data, ASN1_ENUMERATED)) return false;
    1059     3058824 :         while (!data->has_error && asn1_tag_remaining(data)>0) {
    1060        1782 :                 uint8_t b;
    1061     1529412 :                 if (!asn1_read_uint8(data, &b)) {
    1062           0 :                         return false;
    1063             :                 }
    1064     1529412 :                 if (*v & val_will_wrap) {
    1065             :                         /*
    1066             :                          * There is something already in
    1067             :                          * the top byte of the int. If we
    1068             :                          * shift left by 8 it's going to
    1069             :                          * wrap. Prevent this.
    1070             :                          */
    1071           0 :                         data->has_error = true;
    1072           0 :                         return false;
    1073             :                 }
    1074             :                 /*
    1075             :                  * To please/fool the Undefined Behaviour Sanitizer we cast to
    1076             :                  * unsigned for the left shift.
    1077             :                  */
    1078     1529412 :                 *v = ((unsigned int)*v << 8) + b;
    1079     1529412 :                 if (*v < 0) {
    1080             :                         /* ASN1_ENUMERATED can't be -ve. */
    1081           0 :                         data->has_error = true;
    1082           0 :                         return false;
    1083             :                 }
    1084             :         }
    1085     1529412 :         return asn1_end_tag(data);
    1086             : }
    1087             : 
    1088             : /* write an enumerated value to the stream */
    1089     1641768 : bool asn1_write_enumerated(struct asn1_data *data, uint8_t v)
    1090             : {
    1091     1641768 :         if (!asn1_push_tag(data, ASN1_ENUMERATED)) return false;
    1092     1641768 :         if (!asn1_write_uint8(data, v)) return false;
    1093     1641768 :         return asn1_pop_tag(data);
    1094             : }
    1095             : 
    1096             : /*
    1097             :   Get us the data just written without copying
    1098             : */
    1099     2864645 : bool asn1_blob(const struct asn1_data *asn1, DATA_BLOB *blob)
    1100             : {
    1101     2864645 :         if (asn1->has_error) {
    1102           0 :                 return false;
    1103             :         }
    1104     2864645 :         if (asn1->nesting != NULL) {
    1105           0 :                 return false;
    1106             :         }
    1107     2864645 :         blob->data = asn1->data;
    1108     2864645 :         blob->length = asn1->length;
    1109     2864645 :         return true;
    1110             : }
    1111             : 
    1112     2864422 : bool asn1_extract_blob(struct asn1_data *asn1, TALLOC_CTX *mem_ctx,
    1113             :                        DATA_BLOB *pblob)
    1114             : {
    1115        9684 :         DATA_BLOB blob;
    1116             : 
    1117     2864422 :         if (!asn1_blob(asn1, &blob)) {
    1118           0 :                 return false;
    1119             :         }
    1120             : 
    1121     2864422 :         *pblob = (DATA_BLOB) { .length = blob.length };
    1122     2864422 :         pblob->data = talloc_move(mem_ctx, &blob.data);
    1123             : 
    1124             :         /*
    1125             :          * Stop access from here on
    1126             :          */
    1127     2864422 :         asn1->has_error = true;
    1128             : 
    1129     2864422 :         return true;
    1130             : }
    1131             : 
    1132             : /*
    1133             :   Fill in an asn1 struct without making a copy
    1134             : */
    1135     2026630 : void asn1_load_nocopy(struct asn1_data *data, uint8_t *buf, size_t len)
    1136             : {
    1137             :         /*
    1138             :          * Save max_depth
    1139             :          */
    1140     2026630 :         unsigned max_depth = data->max_depth;
    1141     2026630 :         ZERO_STRUCTP(data);
    1142     2026630 :         data->data = buf;
    1143     2026630 :         data->length = len;
    1144     2026630 :         data->max_depth = max_depth;
    1145     2026630 : }
    1146             : 
    1147     4655062 : int asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size)
    1148             : {
    1149       11798 :         struct asn1_data asn1;
    1150       11798 :         size_t size;
    1151       11798 :         bool ok;
    1152             : 
    1153     4655062 :         ZERO_STRUCT(asn1);
    1154     4655062 :         asn1.data = blob.data;
    1155     4655062 :         asn1.length = blob.length;
    1156             : 
    1157     4655062 :         ok = asn1_peek_tag_needed_size(&asn1, tag, &size);
    1158     4655062 :         if (!ok) {
    1159      337507 :                 return EMSGSIZE;
    1160             :         }
    1161             : 
    1162     4313049 :         if (size > blob.length) {
    1163     2019110 :                 *packet_size = size;
    1164     2019110 :                 return EAGAIN;
    1165             :         }
    1166             : 
    1167     2293939 :         *packet_size = size;
    1168     2293939 :         return 0;
    1169             : }
    1170             : 
    1171             : /*
    1172             :  * Get the length of the ASN.1 data
    1173             :  */
    1174      367174 : size_t asn1_get_length(const struct asn1_data *asn1) {
    1175      367174 :         return asn1->length;
    1176             : }

Generated by: LCOV version 1.14