LCOV - code coverage report
Current view: top level - third_party/heimdal/lib/asn1 - oid_resolution.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 0 120 0.0 %
Date: 2024-04-21 15:09:00 Functions: 0 9 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2019 Kungliga Tekniska Högskolan
       3             :  * (Royal Institute of Technology, Stockholm, Sweden).
       4             :  * All rights reserved.
       5             :  *
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions
       8             :  * are met:
       9             :  *
      10             :  * 1. Redistributions of source code must retain the above copyright
      11             :  *    notice, this list of conditions and the following disclaimer.
      12             :  *
      13             :  * 2. Redistributions in binary form must reproduce the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer in the
      15             :  *    documentation and/or other materials provided with the distribution.
      16             :  *
      17             :  * 3. Neither the name of the Institute nor the names of its contributors
      18             :  *    may be used to endorse or promote products derived from this software
      19             :  *    without specific prior written permission.
      20             :  *
      21             :  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
      22             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      23             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
      25             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      26             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      27             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      28             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      29             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      30             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      31             :  * SUCH DAMAGE.
      32             :  */
      33             : 
      34             : #include "der_locl.h"
      35             : #include <hex.h>
      36             : 
      37             : #include "cms_asn1.h"
      38             : #include "crmf_asn1.h"
      39             : #include "digest_asn1.h"
      40             : #include "krb5_asn1.h"
      41             : #include "kx509_asn1.h"
      42             : #include "ocsp_asn1.h"
      43             : #include "pkcs10_asn1.h"
      44             : #include "pkcs12_asn1.h"
      45             : #include "pkcs8_asn1.h"
      46             : #include "pkcs9_asn1.h"
      47             : #include "pkinit_asn1.h"
      48             : #include "rfc2459_asn1.h"
      49             : #include "rfc4108_asn1.h"
      50             : 
      51             : 
      52             : struct sym_oid {
      53             :     const char *sym;
      54             :     const heim_oid *oid;
      55             : };
      56             : 
      57             : #ifndef WIN32
      58             : #define DEFINE_OID_WITH_NAME(sym) \
      59             :     { #sym, &asn1_oid_ ## sym },
      60             : 
      61             : static const struct sym_oid sym_oids[] = {
      62             : #include "cms_asn1_oids.c"
      63             : #include "crmf_asn1_oids.c"
      64             : #include "digest_asn1_oids.c"
      65             : #include "krb5_asn1_oids.c"
      66             : #include "kx509_asn1_oids.c"
      67             : #include "ocsp_asn1_oids.c"
      68             : #include "pkcs10_asn1_oids.c"
      69             : #include "pkcs12_asn1_oids.c"
      70             : #include "pkcs8_asn1_oids.c"
      71             : #include "pkcs9_asn1_oids.c"
      72             : #include "pkinit_asn1_oids.c"
      73             : #include "rfc2459_asn1_oids.c"
      74             : #include "rfc4108_asn1_oids.c"
      75             : };
      76             : 
      77             : static size_t num_sym_oids = sizeof(sym_oids) / sizeof(sym_oids[0]);
      78             : 
      79             : #undef DEFINE_OID_WITH_NAME
      80             : 
      81             : #define init_sym_oids()
      82             : 
      83             : #else
      84             : 
      85             : /*
      86             :  * We can't use C99 non-literal initializers for static objects in the Windows
      87             :  * build...
      88             :  */
      89             : 
      90             : static struct sym_oid *sym_oids;
      91             : static size_t num_sym_oids;
      92             : 
      93             : #define DEFINE_OID_WITH_NAME(sym) (c++);
      94             : static size_t
      95             : count_sym_oids(void)
      96             : {
      97             :     size_t c = 0;
      98             : #include "cms_asn1_oids.c"
      99             : #include "crmf_asn1_oids.c"
     100             : #include "digest_asn1_oids.c"
     101             : #include "krb5_asn1_oids.c"
     102             : #include "kx509_asn1_oids.c"
     103             : #include "ocsp_asn1_oids.c"
     104             : #include "pkcs10_asn1_oids.c"
     105             : #include "pkcs12_asn1_oids.c"
     106             : #include "pkcs8_asn1_oids.c"
     107             : #include "pkcs9_asn1_oids.c"
     108             : #include "pkinit_asn1_oids.c"
     109             : #include "rfc2459_asn1_oids.c"
     110             :     return c;
     111             : }
     112             : #undef DEFINE_OID_WITH_NAME
     113             : 
     114             : #define DEFINE_OID_WITH_NAME(s) \
     115             :     tmp[i].sym = #s; \
     116             :     tmp[i++].oid = &asn1_oid_ ## s;
     117             : 
     118             : static void
     119             : init_sym_oids(void)
     120             : {
     121             :     static struct sym_oid *tmp;
     122             :     size_t i = 0;
     123             :     size_t c;
     124             : 
     125             :     if (!sym_oids &&
     126             :         (c = count_sym_oids()) &&
     127             :         (tmp = calloc(c, sizeof(tmp[0])))) {
     128             : #include "cms_asn1_oids.c"
     129             : #include "crmf_asn1_oids.c"
     130             : #include "digest_asn1_oids.c"
     131             : #include "krb5_asn1_oids.c"
     132             : #include "kx509_asn1_oids.c"
     133             : #include "ocsp_asn1_oids.c"
     134             : #include "pkcs10_asn1_oids.c"
     135             : #include "pkcs12_asn1_oids.c"
     136             : #include "pkcs8_asn1_oids.c"
     137             : #include "pkcs9_asn1_oids.c"
     138             : #include "pkinit_asn1_oids.c"
     139             : #include "rfc2459_asn1_oids.c"
     140             :         num_sym_oids = c;
     141             :         sym_oids = tmp;
     142             :     }
     143             : }
     144             : #undef DEFINE_OID_WITH_NAME
     145             : 
     146             : #endif
     147             : 
     148             : static struct sym_oid *sym_oids_sorted_by_name;
     149             : static struct sym_oid *sym_oids_sorted_by_oid;
     150             : 
     151             : static int
     152           0 : sym_cmp_name(const void *va, const void *vb)
     153             : {
     154           0 :     const struct sym_oid *a = va;
     155           0 :     const struct sym_oid *b = vb;
     156             : 
     157           0 :     return (strcmp(a->sym, b->sym));
     158             : }
     159             : 
     160             : static int
     161           0 : sym_cmp_oid(const void *va, const void *vb)
     162             : {
     163           0 :     const struct sym_oid *a = va;
     164           0 :     const struct sym_oid *b = vb;
     165             : 
     166           0 :     return der_heim_oid_cmp(a->oid, b->oid);
     167             : }
     168             : 
     169             : static struct sym_oid *
     170           0 : sort_sym_oids(int (*cmp)(const void *, const void *))
     171             : {
     172           0 :     struct sym_oid *tmp;
     173             : 
     174           0 :     init_sym_oids();
     175           0 :     if ((tmp = calloc(num_sym_oids, sizeof(tmp[0]))) == NULL)
     176           0 :         return NULL;
     177             : 
     178           0 :     memcpy(tmp, sym_oids, num_sym_oids * sizeof(tmp[0]));
     179           0 :     qsort(tmp, num_sym_oids, sizeof(struct sym_oid), cmp);
     180           0 :     return tmp;
     181             : }
     182             : 
     183             : static int
     184           0 : fix_oid_name(const char **namep, char **freeme)
     185             : {
     186           0 :     char *dash = strchr(*namep, '-');
     187             : 
     188           0 :     *freeme = NULL;
     189           0 :     if (dash == NULL)
     190           0 :         return 0;
     191           0 :     if ((*freeme = strdup(*namep)) == NULL)
     192           0 :         return ENOMEM;
     193           0 :     *namep = *freeme;
     194           0 :     for (dash = strchr(*namep, '-'); dash; dash = strchr(dash, '-'))
     195           0 :         *dash = '_';
     196           0 :     return 0;
     197             : }
     198             : 
     199             : int ASN1CALL
     200           0 : der_find_heim_oid_by_name(const char *str, const heim_oid **oid)
     201             : {
     202           0 :     size_t right = num_sym_oids - 1;
     203           0 :     size_t left = 0;
     204           0 :     char *s = NULL;
     205           0 :     int ret;
     206             : 
     207           0 :     *oid = NULL;
     208           0 :     if (sym_oids_sorted_by_name == NULL &&
     209           0 :         (sym_oids_sorted_by_name = sort_sym_oids(sym_cmp_name)) == NULL)
     210           0 :         return ENOMEM;
     211             : 
     212           0 :     if ((ret = fix_oid_name(&str, &s)))
     213           0 :         return ret;
     214             : 
     215           0 :     while (left <= right) {
     216           0 :         size_t mid = left + (right - left) / 2;
     217           0 :         int cmp;
     218             : 
     219           0 :         cmp = strcmp(str, sym_oids_sorted_by_name[mid].sym);
     220           0 :         if (cmp == 0) {
     221           0 :             *oid = sym_oids_sorted_by_name[mid].oid;
     222           0 :             free(s);
     223           0 :             return 0;
     224             :         }
     225           0 :         if (cmp < 0 && mid > 0) {/* avoid underflow */
     226           0 :             right = mid - 1;
     227           0 :         } else if (cmp < 0) {
     228           0 :             free(s);
     229           0 :             return -1;
     230             :         } else {
     231           0 :             left = mid + 1;
     232             :         }
     233             :     }
     234           0 :     free(s);
     235           0 :     return -1;
     236             : }
     237             : 
     238             : int ASN1CALL
     239           0 : der_find_or_parse_heim_oid(const char *str, const char *sep, heim_oid *oid)
     240             : {
     241           0 :     const heim_oid *found = NULL;
     242             : 
     243           0 :     switch (der_find_heim_oid_by_name(str, &found)) {
     244           0 :     case 0: return der_copy_oid(found, oid);
     245           0 :     case -1: return der_parse_heim_oid(str, sep, oid);
     246           0 :     default: return ENOMEM;
     247             :     }
     248             : }
     249             : 
     250             : int ASN1CALL
     251           0 : der_find_heim_oid_by_oid(const heim_oid *oid, const char **name)
     252             : {
     253           0 :     size_t right = num_sym_oids;
     254           0 :     size_t left = 0;
     255             : 
     256           0 :     *name = NULL;
     257           0 :     if (sym_oids_sorted_by_oid == NULL &&
     258           0 :         (sym_oids_sorted_by_oid = sort_sym_oids(sym_cmp_oid)) == NULL)
     259           0 :         return ENOMEM;
     260             : 
     261           0 :     while (left <= right) {
     262           0 :         size_t mid = (left + right) >> 1;
     263           0 :         int cmp;
     264             : 
     265           0 :         cmp = der_heim_oid_cmp(oid, sym_oids_sorted_by_oid[mid].oid);
     266           0 :         if (cmp == 0) {
     267           0 :             *name = sym_oids_sorted_by_oid[mid].sym;
     268           0 :             return 0;
     269             :         }
     270           0 :         if (cmp < 0 && mid)
     271           0 :             right = mid - 1;
     272           0 :         else if (cmp < 0)
     273           0 :             return -1;
     274           0 :         else if (mid < num_sym_oids - 1)
     275           0 :             left = mid + 1;
     276             :         else
     277           0 :             return -1;
     278             :     }
     279           0 :     return -1;
     280             : }
     281             : 
     282             : int ASN1CALL
     283           0 : der_match_heim_oid_by_name(const char *str, int *c, const heim_oid **oid)
     284             : {
     285           0 :     size_t i;
     286           0 :     char *s = NULL;
     287           0 :     int ret;
     288             : 
     289           0 :     if ((ret = fix_oid_name(&str, &s)))
     290           0 :         return ret;
     291             : 
     292           0 :     if (*c < 0)
     293           0 :         *c = 0;
     294             : 
     295           0 :     init_sym_oids();
     296           0 :     for (i = (size_t)*c; i < num_sym_oids; i++) {
     297             :         /*
     298             :          * XXX We need a lib/roken strcasestr(), or maybe we should support
     299             :          * globbing here.
     300             :          */
     301           0 :         if (strstr(sym_oids[i].sym, str)) {
     302           0 :             *oid = sym_oids[i].oid;
     303           0 :             free(s);
     304           0 :             if (i >= INT_MAX)
     305           0 :                 return -1;
     306           0 :             *c = i + 1; /* num_sym_oids is much less than INT_MAX */
     307           0 :             return 0;
     308             :         }
     309             :     }
     310           0 :     free(s);
     311           0 :     return -1;
     312             : }
     313             : 
     314             : /* Warning: der_print_heim_oid_sym() will not round-trip */
     315             : 
     316             : int ASN1CALL
     317           0 : der_print_heim_oid_sym(const heim_oid *oid, char delim, char **strp)
     318             : {
     319           0 :     const char *sym;
     320           0 :     char *s1 = NULL;
     321           0 :     char *s2 = NULL;
     322           0 :     char *p;
     323           0 :     int ret;
     324             : 
     325           0 :     if (der_find_heim_oid_by_oid(oid, &sym))
     326           0 :         return der_print_heim_oid(oid, delim, strp);
     327             : 
     328           0 :     if ((ret = der_print_heim_oid(oid, delim, &s1)))
     329           0 :         return ret;
     330           0 :     if (asprintf(&s2, "%s (%s)", s1, sym) == -1 || s2 == NULL) {
     331           0 :         *strp = s1;
     332           0 :         return 0;
     333             :     }
     334           0 :     for (p = s2 + strlen(s1) + 1; *p; p++) {
     335           0 :         if (*p == '_')
     336           0 :             *p = '-';
     337             :     }
     338           0 :     *strp = s2;
     339           0 :     free(s1);
     340           0 :     return 0;
     341             : }

Generated by: LCOV version 1.14