⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 v3_addr.c

📁 OpenSSL 0.9.8k 最新版OpenSSL
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Contributed to the OpenSSL Project by the American Registry for * Internet Numbers ("ARIN"). *//* ==================================================================== * Copyright (c) 2006 The OpenSSL Project.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer.  * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * 3. All advertising materials mentioning features or use of this *    software must display the following acknowledgment: *    "This product includes software developed by the OpenSSL Project *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" * * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to *    endorse or promote products derived from this software without *    prior written permission. For written permission, please contact *    licensing@OpenSSL.org. * * 5. Products derived from this software may not be called "OpenSSL" *    nor may "OpenSSL" appear in their names without prior written *    permission of the OpenSSL Project. * * 6. Redistributions of any form whatsoever must retain the following *    acknowledgment: *    "This product includes software developed by the OpenSSL Project *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" * * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This product includes cryptographic software written by Eric Young * (eay@cryptsoft.com).  This product includes software written by Tim * Hudson (tjh@cryptsoft.com). *//* * Implementation of RFC 3779 section 2.2. */#include <stdio.h>#include <stdlib.h>#include "cryptlib.h"#include <openssl/conf.h>#include <openssl/asn1.h>#include <openssl/asn1t.h>#include <openssl/buffer.h>#include <openssl/x509v3.h>#ifndef OPENSSL_NO_RFC3779/* * OpenSSL ASN.1 template translation of RFC 3779 2.2.3. */ASN1_SEQUENCE(IPAddressRange) = {  ASN1_SIMPLE(IPAddressRange, min, ASN1_BIT_STRING),  ASN1_SIMPLE(IPAddressRange, max, ASN1_BIT_STRING)} ASN1_SEQUENCE_END(IPAddressRange)ASN1_CHOICE(IPAddressOrRange) = {  ASN1_SIMPLE(IPAddressOrRange, u.addressPrefix, ASN1_BIT_STRING),  ASN1_SIMPLE(IPAddressOrRange, u.addressRange,  IPAddressRange)} ASN1_CHOICE_END(IPAddressOrRange)ASN1_CHOICE(IPAddressChoice) = {  ASN1_SIMPLE(IPAddressChoice,      u.inherit,           ASN1_NULL),  ASN1_SEQUENCE_OF(IPAddressChoice, u.addressesOrRanges, IPAddressOrRange)} ASN1_CHOICE_END(IPAddressChoice)ASN1_SEQUENCE(IPAddressFamily) = {  ASN1_SIMPLE(IPAddressFamily, addressFamily,   ASN1_OCTET_STRING),  ASN1_SIMPLE(IPAddressFamily, ipAddressChoice, IPAddressChoice)} ASN1_SEQUENCE_END(IPAddressFamily)ASN1_ITEM_TEMPLATE(IPAddrBlocks) =   ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0,			IPAddrBlocks, IPAddressFamily)ASN1_ITEM_TEMPLATE_END(IPAddrBlocks)IMPLEMENT_ASN1_FUNCTIONS(IPAddressRange)IMPLEMENT_ASN1_FUNCTIONS(IPAddressOrRange)IMPLEMENT_ASN1_FUNCTIONS(IPAddressChoice)IMPLEMENT_ASN1_FUNCTIONS(IPAddressFamily)/* * How much buffer space do we need for a raw address? */#define ADDR_RAW_BUF_LEN	16/* * What's the address length associated with this AFI? */static int length_from_afi(const unsigned afi){  switch (afi) {  case IANA_AFI_IPV4:    return 4;  case IANA_AFI_IPV6:    return 16;  default:    return 0;  }}/* * Extract the AFI from an IPAddressFamily. */unsigned int v3_addr_get_afi(const IPAddressFamily *f){  return ((f != NULL &&	   f->addressFamily != NULL &&	   f->addressFamily->data != NULL)	  ? ((f->addressFamily->data[0] << 8) |	     (f->addressFamily->data[1]))	  : 0);}/* * Expand the bitstring form of an address into a raw byte array. * At the moment this is coded for simplicity, not speed. */static void addr_expand(unsigned char *addr,			const ASN1_BIT_STRING *bs,			const int length,			const unsigned char fill){  OPENSSL_assert(bs->length >= 0 && bs->length <= length);  if (bs->length > 0) {    memcpy(addr, bs->data, bs->length);    if ((bs->flags & 7) != 0) {      unsigned char mask = 0xFF >> (8 - (bs->flags & 7));      if (fill == 0)	addr[bs->length - 1] &= ~mask;      else	addr[bs->length - 1] |= mask;    }  }  memset(addr + bs->length, fill, length - bs->length);}/* * Extract the prefix length from a bitstring. */#define addr_prefixlen(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7)))/* * i2r handler for one address bitstring. */static int i2r_address(BIO *out,		       const unsigned afi,		       const unsigned char fill,		       const ASN1_BIT_STRING *bs){  unsigned char addr[ADDR_RAW_BUF_LEN];  int i, n;  switch (afi) {  case IANA_AFI_IPV4:    addr_expand(addr, bs, 4, fill);    BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);    break;  case IANA_AFI_IPV6:    addr_expand(addr, bs, 16, fill);    for (n = 16; n > 1 && addr[n-1] == 0x00 && addr[n-2] == 0x00; n -= 2)      ;    for (i = 0; i < n; i += 2)      BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i+1], (i < 14 ? ":" : ""));    if (i < 16)      BIO_puts(out, ":");    if (i == 0)      BIO_puts(out, ":");    break;  default:    for (i = 0; i < bs->length; i++)      BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), bs->data[i]);    BIO_printf(out, "[%d]", (int) (bs->flags & 7));    break;  }  return 1;}/* * i2r handler for a sequence of addresses and ranges. */static int i2r_IPAddressOrRanges(BIO *out,				 const int indent,				 const IPAddressOrRanges *aors,				 const unsigned afi){  int i;  for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) {    const IPAddressOrRange *aor = sk_IPAddressOrRange_value(aors, i);    BIO_printf(out, "%*s", indent, "");    switch (aor->type) {    case IPAddressOrRange_addressPrefix:      if (!i2r_address(out, afi, 0x00, aor->u.addressPrefix))	return 0;      BIO_printf(out, "/%d\n", addr_prefixlen(aor->u.addressPrefix));      continue;    case IPAddressOrRange_addressRange:      if (!i2r_address(out, afi, 0x00, aor->u.addressRange->min))	return 0;      BIO_puts(out, "-");      if (!i2r_address(out, afi, 0xFF, aor->u.addressRange->max))	return 0;      BIO_puts(out, "\n");      continue;    }  }  return 1;}/* * i2r handler for an IPAddrBlocks extension. */static int i2r_IPAddrBlocks(X509V3_EXT_METHOD *method,			    void *ext,			    BIO *out,			    int indent){  const IPAddrBlocks *addr = ext;  int i;  for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {    IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);    const unsigned int afi = v3_addr_get_afi(f);    switch (afi) {    case IANA_AFI_IPV4:      BIO_printf(out, "%*sIPv4", indent, "");      break;    case IANA_AFI_IPV6:      BIO_printf(out, "%*sIPv6", indent, "");      break;    default:      BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi);      break;    }    if (f->addressFamily->length > 2) {      switch (f->addressFamily->data[2]) {      case   1:	BIO_puts(out, " (Unicast)");	break;      case   2:	BIO_puts(out, " (Multicast)");	break;      case   3:	BIO_puts(out, " (Unicast/Multicast)");	break;      case   4:	BIO_puts(out, " (MPLS)");	break;      case  64:	BIO_puts(out, " (Tunnel)");	break;      case  65:	BIO_puts(out, " (VPLS)");	break;      case  66:	BIO_puts(out, " (BGP MDT)");	break;      case 128:	BIO_puts(out, " (MPLS-labeled VPN)");	break;      default:  	BIO_printf(out, " (Unknown SAFI %u)",		   (unsigned) f->addressFamily->data[2]);	break;      }    }    switch (f->ipAddressChoice->type) {    case IPAddressChoice_inherit:      BIO_puts(out, ": inherit\n");      break;    case IPAddressChoice_addressesOrRanges:      BIO_puts(out, ":\n");      if (!i2r_IPAddressOrRanges(out,				 indent + 2,				 f->ipAddressChoice->u.addressesOrRanges,				 afi))	return 0;      break;    }  }  return 1;}/* * Sort comparison function for a sequence of IPAddressOrRange * elements. */static int IPAddressOrRange_cmp(const IPAddressOrRange *a,				const IPAddressOrRange *b,				const int length){  unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN];  int prefixlen_a = 0;  int prefixlen_b = 0;  int r;  switch (a->type) {  case IPAddressOrRange_addressPrefix:    addr_expand(addr_a, a->u.addressPrefix, length, 0x00);    prefixlen_a = addr_prefixlen(a->u.addressPrefix);    break;  case IPAddressOrRange_addressRange:    addr_expand(addr_a, a->u.addressRange->min, length, 0x00);    prefixlen_a = length * 8;    break;  }  switch (b->type) {  case IPAddressOrRange_addressPrefix:    addr_expand(addr_b, b->u.addressPrefix, length, 0x00);    prefixlen_b = addr_prefixlen(b->u.addressPrefix);    break;  case IPAddressOrRange_addressRange:    addr_expand(addr_b, b->u.addressRange->min, length, 0x00);    prefixlen_b = length * 8;    break;  }  if ((r = memcmp(addr_a, addr_b, length)) != 0)    return r;  else    return prefixlen_a - prefixlen_b;}/* * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort() * comparision routines are only allowed two arguments. */static int v4IPAddressOrRange_cmp(const IPAddressOrRange * const *a,				  const IPAddressOrRange * const *b){  return IPAddressOrRange_cmp(*a, *b, 4);}/* * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort() * comparision routines are only allowed two arguments. */static int v6IPAddressOrRange_cmp(const IPAddressOrRange * const *a,				  const IPAddressOrRange * const *b){  return IPAddressOrRange_cmp(*a, *b, 16);}/* * Calculate whether a range collapses to a prefix. * See last paragraph of RFC 3779 2.2.3.7. */static int range_should_be_prefix(const unsigned char *min,				  const unsigned char *max,				  const int length){  unsigned char mask;  int i, j;  for (i = 0; i < length && min[i] == max[i]; i++)    ;  for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--)    ;  if (i < j)    return -1;  if (i > j)    return i * 8;  mask = min[i] ^ max[i];  switch (mask) {  case 0x01: j = 7; break;  case 0x03: j = 6; break;  case 0x07: j = 5; break;  case 0x0F: j = 4; break;  case 0x1F: j = 3; break;  case 0x3F: j = 2; break;  case 0x7F: j = 1; break;  default:   return -1;  }  if ((min[i] & mask) != 0 || (max[i] & mask) != mask)    return -1;  else    return i * 8 + j;}/* * Construct a prefix. */static int make_addressPrefix(IPAddressOrRange **result,			      unsigned char *addr,			      const int prefixlen){  int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8;  IPAddressOrRange *aor = IPAddressOrRange_new();  if (aor == NULL)    return 0;  aor->type = IPAddressOrRange_addressPrefix;  if (aor->u.addressPrefix == NULL &&      (aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL)    goto err;  if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen))    goto err;  aor->u.addressPrefix->flags &= ~7;  aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT;  if (bitlen > 0) {    aor->u.addressPrefix->data[bytelen - 1] &= ~(0xFF >> bitlen);    aor->u.addressPrefix->flags |= 8 - bitlen;  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -