root/lib/oid_registry.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. look_up_OID
  2. sprint_oid
  3. sprint_OID

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /* ASN.1 Object identifier (OID) registry
   3  *
   4  * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
   5  * Written by David Howells (dhowells@redhat.com)
   6  */
   7 
   8 #include <linux/module.h>
   9 #include <linux/export.h>
  10 #include <linux/oid_registry.h>
  11 #include <linux/kernel.h>
  12 #include <linux/errno.h>
  13 #include <linux/bug.h>
  14 #include "oid_registry_data.c"
  15 
  16 MODULE_DESCRIPTION("OID Registry");
  17 MODULE_AUTHOR("Red Hat, Inc.");
  18 MODULE_LICENSE("GPL");
  19 
  20 /**
  21  * look_up_OID - Find an OID registration for the specified data
  22  * @data: Binary representation of the OID
  23  * @datasize: Size of the binary representation
  24  */
  25 enum OID look_up_OID(const void *data, size_t datasize)
  26 {
  27         const unsigned char *octets = data;
  28         enum OID oid;
  29         unsigned char xhash;
  30         unsigned i, j, k, hash;
  31         size_t len;
  32 
  33         /* Hash the OID data */
  34         hash = datasize - 1;
  35 
  36         for (i = 0; i < datasize; i++)
  37                 hash += octets[i] * 33;
  38         hash = (hash >> 24) ^ (hash >> 16) ^ (hash >> 8) ^ hash;
  39         hash &= 0xff;
  40 
  41         /* Binary search the OID registry.  OIDs are stored in ascending order
  42          * of hash value then ascending order of size and then in ascending
  43          * order of reverse value.
  44          */
  45         i = 0;
  46         k = OID__NR;
  47         while (i < k) {
  48                 j = (i + k) / 2;
  49 
  50                 xhash = oid_search_table[j].hash;
  51                 if (xhash > hash) {
  52                         k = j;
  53                         continue;
  54                 }
  55                 if (xhash < hash) {
  56                         i = j + 1;
  57                         continue;
  58                 }
  59 
  60                 oid = oid_search_table[j].oid;
  61                 len = oid_index[oid + 1] - oid_index[oid];
  62                 if (len > datasize) {
  63                         k = j;
  64                         continue;
  65                 }
  66                 if (len < datasize) {
  67                         i = j + 1;
  68                         continue;
  69                 }
  70 
  71                 /* Variation is most likely to be at the tail end of the
  72                  * OID, so do the comparison in reverse.
  73                  */
  74                 while (len > 0) {
  75                         unsigned char a = oid_data[oid_index[oid] + --len];
  76                         unsigned char b = octets[len];
  77                         if (a > b) {
  78                                 k = j;
  79                                 goto next;
  80                         }
  81                         if (a < b) {
  82                                 i = j + 1;
  83                                 goto next;
  84                         }
  85                 }
  86                 return oid;
  87         next:
  88                 ;
  89         }
  90 
  91         return OID__NR;
  92 }
  93 EXPORT_SYMBOL_GPL(look_up_OID);
  94 
  95 /*
  96  * sprint_OID - Print an Object Identifier into a buffer
  97  * @data: The encoded OID to print
  98  * @datasize: The size of the encoded OID
  99  * @buffer: The buffer to render into
 100  * @bufsize: The size of the buffer
 101  *
 102  * The OID is rendered into the buffer in "a.b.c.d" format and the number of
 103  * bytes is returned.  -EBADMSG is returned if the data could not be intepreted
 104  * and -ENOBUFS if the buffer was too small.
 105  */
 106 int sprint_oid(const void *data, size_t datasize, char *buffer, size_t bufsize)
 107 {
 108         const unsigned char *v = data, *end = v + datasize;
 109         unsigned long num;
 110         unsigned char n;
 111         size_t ret;
 112         int count;
 113 
 114         if (v >= end)
 115                 goto bad;
 116 
 117         n = *v++;
 118         ret = count = snprintf(buffer, bufsize, "%u.%u", n / 40, n % 40);
 119         if (count >= bufsize)
 120                 return -ENOBUFS;
 121         buffer += count;
 122         bufsize -= count;
 123 
 124         while (v < end) {
 125                 num = 0;
 126                 n = *v++;
 127                 if (!(n & 0x80)) {
 128                         num = n;
 129                 } else {
 130                         num = n & 0x7f;
 131                         do {
 132                                 if (v >= end)
 133                                         goto bad;
 134                                 n = *v++;
 135                                 num <<= 7;
 136                                 num |= n & 0x7f;
 137                         } while (n & 0x80);
 138                 }
 139                 ret += count = snprintf(buffer, bufsize, ".%lu", num);
 140                 if (count >= bufsize)
 141                         return -ENOBUFS;
 142                 buffer += count;
 143                 bufsize -= count;
 144         }
 145 
 146         return ret;
 147 
 148 bad:
 149         snprintf(buffer, bufsize, "(bad)");
 150         return -EBADMSG;
 151 }
 152 EXPORT_SYMBOL_GPL(sprint_oid);
 153 
 154 /**
 155  * sprint_OID - Print an Object Identifier into a buffer
 156  * @oid: The OID to print
 157  * @buffer: The buffer to render into
 158  * @bufsize: The size of the buffer
 159  *
 160  * The OID is rendered into the buffer in "a.b.c.d" format and the number of
 161  * bytes is returned.
 162  */
 163 int sprint_OID(enum OID oid, char *buffer, size_t bufsize)
 164 {
 165         int ret;
 166 
 167         BUG_ON(oid >= OID__NR);
 168 
 169         ret = sprint_oid(oid_data + oid_index[oid],
 170                          oid_index[oid + 1] - oid_index[oid],
 171                          buffer, bufsize);
 172         BUG_ON(ret == -EBADMSG);
 173         return ret;
 174 }
 175 EXPORT_SYMBOL_GPL(sprint_OID);

/* [<][>][^][v][top][bottom][index][help] */