18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ASN.1 DER parsing 350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * Copyright (c) 2006-2014, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "asn1.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidtstruct asn1_oid asn1_sha1_oid = { 1550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt .oid = { 1, 3, 14, 3, 2, 26 }, 1650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt .len = 6 1750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt}; 1850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 1950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidtstruct asn1_oid asn1_sha256_oid = { 2050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt .oid = { 2, 16, 840, 1, 101, 3, 4, 2, 1 }, 2150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt .len = 9 2250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt}; 2350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 2450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint asn1_get_next(const u8 *buf, size_t len, struct asn1_hdr *hdr) 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 tmp; 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(hdr, 0, sizeof(*hdr)); 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = buf + len; 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->identifier = *pos++; 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->class = hdr->identifier >> 6; 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->constructed = !!(hdr->identifier & (1 << 5)); 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((hdr->identifier & 0x1f) == 0x1f) { 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->tag = 0; 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt do { 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos >= end) { 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ASN.1: Identifier " 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "underflow"); 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = *pos++; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_MSGDUMP, "ASN.1: Extended tag data: " 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "0x%02x", tmp); 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->tag = (hdr->tag << 7) | (tmp & 0x7f); 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } while (tmp & 0x80); 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->tag = hdr->identifier & 0x1f; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = *pos++; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp & 0x80) { 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp == 0xff) { 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ASN.1: Reserved length " 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "value 0xff used"); 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp &= 0x7f; /* number of subsequent octets */ 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->length = 0; 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp > 4) { 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ASN.1: Too long length field"); 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (tmp--) { 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos >= end) { 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ASN.1: Length " 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "underflow"); 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->length = (hdr->length << 8) | *pos++; 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Short form - length 0..127 in one octet */ 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->length = tmp; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end < pos || hdr->length > (unsigned int) (end - pos)) { 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ASN.1: Contents underflow"); 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->payload = pos; 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint asn1_parse_oid(const u8 *buf, size_t len, struct asn1_oid *oid) 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long val; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 tmp; 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(oid, 0, sizeof(*oid)); 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = buf + len; 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < end) { 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt val = 0; 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt do { 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos >= end) 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = *pos++; 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt val = (val << 7) | (tmp & 0x7f); 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } while (tmp & 0x80); 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (oid->len >= ASN1_MAX_OID_LEN) { 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ASN.1: Too long OID value"); 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (oid->len == 0) { 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The first octet encodes the first two object 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * identifier components in (X*40) + Y formula. 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * X = 0..2. 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt oid->oid[0] = val / 40; 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (oid->oid[0] > 2) 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt oid->oid[0] = 2; 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt oid->oid[1] = val - oid->oid[0] * 40; 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt oid->len = 2; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt oid->oid[oid->len++] = val; 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint asn1_get_oid(const u8 *buf, size_t len, struct asn1_oid *oid, 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 **next) 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct asn1_hdr hdr; 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (asn1_get_next(buf, len, &hdr) < 0 || hdr.length == 0) 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_OID) { 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ASN.1: Expected OID - found class %d " 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "tag 0x%x", hdr.class, hdr.tag); 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *next = hdr.payload + hdr.length; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return asn1_parse_oid(hdr.payload, hdr.length, oid); 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidtvoid asn1_oid_to_str(const struct asn1_oid *oid, char *buf, size_t len) 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pos = buf; 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len == 0) 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[0] = '\0'; 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < oid->len; i++) { 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, buf + len - pos, 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s%lu", 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i == 0 ? "" : ".", oid->oid[i]); 169fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt if (os_snprintf_error(buf + len - pos, ret)) 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[len - 1] = '\0'; 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 rotate_bits(u8 octet) 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 res; 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = 0; 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 8; i++) { 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res <<= 1; 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (octet & 1) 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res |= 1; 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt octet >>= 1; 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtunsigned long asn1_bit_string_to_long(const u8 *buf, size_t len) 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long val = 0; 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos = buf; 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* BER requires that unused bits are zero, so we can ignore the number 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * of unused bits */ 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len >= 2) 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt val |= rotate_bits(*pos++); 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len >= 3) 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt val |= ((unsigned long) rotate_bits(*pos++)) << 8; 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len >= 4) 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt val |= ((unsigned long) rotate_bits(*pos++)) << 16; 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len >= 5) 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt val |= ((unsigned long) rotate_bits(*pos++)) << 24; 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len >= 6) 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "X509: %s - some bits ignored " 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(BIT STRING length %lu)", 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, (unsigned long) len); 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return val; 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 21950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 22050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidtint asn1_oid_equal(const struct asn1_oid *a, const struct asn1_oid *b) 22150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt{ 22250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt size_t i; 22350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 22450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt if (a->len != b->len) 22550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt return 0; 22650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 22750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt for (i = 0; i < a->len; i++) { 22850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt if (a->oid[i] != b->oid[i]) 22950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt return 0; 23050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt } 23150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 23250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt return 1; 23350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt} 234