/* crypto/sha/sha512.c */ /* ==================================================================== * Copyright (c) 2004 The OpenSSL Project. All rights reserved * according to the OpenSSL license [found in ../../LICENSE]. * ==================================================================== */ #include #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512) /* * IMPLEMENTATION NOTES. * * As you might have noticed 32-bit hash algorithms: * * - permit SHA_LONG to be wider than 32-bit (case on CRAY); * - optimized versions implement two transform functions: one operating * on [aligned] data in host byte order and one - on data in input * stream byte order; * - share common byte-order neutral collector and padding function * implementations, ../md32_common.h; * * Neither of the above applies to this SHA-512 implementations. Reasons * [in reverse order] are: * * - it's the only 64-bit hash algorithm for the moment of this writing, * there is no need for common collector/padding implementation [yet]; * - by supporting only one transform function [which operates on * *aligned* data in input stream byte order, big-endian in this case] * we minimize burden of maintenance in two ways: a) collector/padding * function is simpler; b) only one transform function to stare at; * - SHA_LONG64 is required to be exactly 64-bit in order to be able to * apply a number of optimizations to mitigate potential performance * penalties caused by previous design decision; * * Caveat lector. * * Implementation relies on the fact that "long long" is 64-bit on * both 32- and 64-bit platforms. If some compiler vendor comes up * with 128-bit long long, adjustment to sha.h would be required. * As this implementation relies on 64-bit integer type, it's totally * inappropriate for platforms which don't support it, most notably * 16-bit platforms. * */ #include #include #include #include #include #include "cryptlib.h" const char *SHA512_version="SHA-512" OPENSSL_VERSION_PTEXT; #if defined(_M_IX86) || defined(_M_AMD64) || defined(__i386) || defined(__x86_64) #define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA #endif int SHA384_Init (SHA512_CTX *c) { c->h[0]=U64(0xcbbb9d5dc1059ed8); c->h[1]=U64(0x629a292a367cd507); c->h[2]=U64(0x9159015a3070dd17); c->h[3]=U64(0x152fecd8f70e5939); c->h[4]=U64(0x67332667ffc00b31); c->h[5]=U64(0x8eb44a8768581511); c->h[6]=U64(0xdb0c2e0d64f98fa7); c->h[7]=U64(0x47b5481dbefa4fa4); c->Nl=0; c->Nh=0; c->num=0; c->md_len=SHA384_DIGEST_LENGTH; return 1; } int SHA512_Init (SHA512_CTX *c) { c->h[0]=U64(0x6a09e667f3bcc908); c->h[1]=U64(0xbb67ae8584caa73b); c->h[2]=U64(0x3c6ef372fe94f82b); c->h[3]=U64(0xa54ff53a5f1d36f1); c->h[4]=U64(0x510e527fade682d1); c->h[5]=U64(0x9b05688c2b3e6c1f); c->h[6]=U64(0x1f83d9abfb41bd6b); c->h[7]=U64(0x5be0cd19137e2179); c->Nl=0; c->Nh=0; c->num=0; c->md_len=SHA512_DIGEST_LENGTH; return 1; } #ifndef SHA512_ASM static #endif void sha512_block (SHA512_CTX *ctx, const void *in, size_t num); int SHA512_Final (unsigned char *md, SHA512_CTX *c) { unsigned char *p=(unsigned char *)c->u.p; size_t n=c->num; p[n]=0x80; /* There always is a room for one */ n++; if (n > (sizeof(c->u)-16)) memset (p+n,0,sizeof(c->u)-n), n=0, sha512_block (c,p,1); memset (p+n,0,sizeof(c->u)-16-n); #ifdef B_ENDIAN c->u.d[SHA_LBLOCK-2] = c->Nh; c->u.d[SHA_LBLOCK-1] = c->Nl; #else p[sizeof(c->u)-1] = (unsigned char)(c->Nl); p[sizeof(c->u)-2] = (unsigned char)(c->Nl>>8); p[sizeof(c->u)-3] = (unsigned char)(c->Nl>>16); p[sizeof(c->u)-4] = (unsigned char)(c->Nl>>24); p[sizeof(c->u)-5] = (unsigned char)(c->Nl>>32); p[sizeof(c->u)-6] = (unsigned char)(c->Nl>>40); p[sizeof(c->u)-7] = (unsigned char)(c->Nl>>48); p[sizeof(c->u)-8] = (unsigned char)(c->Nl>>56); p[sizeof(c->u)-9] = (unsigned char)(c->Nh); p[sizeof(c->u)-10] = (unsigned char)(c->Nh>>8); p[sizeof(c->u)-11] = (unsigned char)(c->Nh>>16); p[sizeof(c->u)-12] = (unsigned char)(c->Nh>>24); p[sizeof(c->u)-13] = (unsigned char)(c->Nh>>32); p[sizeof(c->u)-14] = (unsigned char)(c->Nh>>40); p[sizeof(c->u)-15] = (unsigned char)(c->Nh>>48); p[sizeof(c->u)-16] = (unsigned char)(c->Nh>>56); #endif sha512_block (c,p,1); if (md==0) return 0; switch (c->md_len) { /* Let compiler decide if it's appropriate to unroll... */ case SHA384_DIGEST_LENGTH: for (n=0;nh[n]; *(md++) = (unsigned char)(t>>56); *(md++) = (unsigned char)(t>>48); *(md++) = (unsigned char)(t>>40); *(md++) = (unsigned char)(t>>32); *(md++) = (unsigned char)(t>>24); *(md++) = (unsigned char)(t>>16); *(md++) = (unsigned char)(t>>8); *(md++) = (unsigned char)(t); } break; case SHA512_DIGEST_LENGTH: for (n=0;nh[n]; *(md++) = (unsigned char)(t>>56); *(md++) = (unsigned char)(t>>48); *(md++) = (unsigned char)(t>>40); *(md++) = (unsigned char)(t>>32); *(md++) = (unsigned char)(t>>24); *(md++) = (unsigned char)(t>>16); *(md++) = (unsigned char)(t>>8); *(md++) = (unsigned char)(t); } break; /* ... as well as make sure md_len is not abused. */ default: return 0; } return 1; } int SHA384_Final (unsigned char *md,SHA512_CTX *c) { return SHA512_Final (md,c); } int SHA512_Update (SHA512_CTX *c, const void *_data, size_t len) { SHA_LONG64 l; unsigned char *p=c->u.p; const unsigned char *data=(const unsigned char *)_data; if (len==0) return 1; l = (c->Nl+(((SHA_LONG64)len)<<3))&U64(0xffffffffffffffff); if (l < c->Nl) c->Nh++; if (sizeof(len)>=8) c->Nh+=(((SHA_LONG64)len)>>61); c->Nl=l; if (c->num != 0) { size_t n = sizeof(c->u) - c->num; if (len < n) { memcpy (p+c->num,data,len), c->num += len; return 1; } else { memcpy (p+c->num,data,n), c->num = 0; len-=n, data+=n; sha512_block (c,p,1); } } if (len >= sizeof(c->u)) { #ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA if ((size_t)data%sizeof(c->u.d[0]) != 0) while (len >= sizeof(c->u)) memcpy (p,data,sizeof(c->u)), sha512_block (c,p,1), len -= sizeof(c->u), data += sizeof(c->u); else #endif sha512_block (c,data,len/sizeof(c->u)), data += len, len %= sizeof(c->u), data -= len; } if (len != 0) memcpy (p,data,len), c->num = (int)len; return 1; } int SHA384_Update (SHA512_CTX *c, const void *data, size_t len
"""
Parse a WHOIS research dump and write out (just) the RPKI-relevant
fields in myrpki-format CSV syntax.

NB: The input data for this script comes from ARIN under an agreement
that allows research use but forbids redistribution, so if you think
you need a copy of the data, please talk to ARIN about it, not us.

Input format used to be RPSL WHOIS dump, but ARIN recently went Java,
so we have to parse a 3.5GB XML "document".  Credit to Liza Daly for
explaining the incantations needed to convince lxml to do this nicely,
see: http://www.ibm.com/developerworks/xml/library/x-hiperfparse/

$Id$

Copyright (C) 2009-2012  Internet Systems Consortium ("ISC")

Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
"""

import sys, lxml.etree

from rpki.csv_utils import csv_writer

def ns(tag):
  return "{http://www.arin.net/bulkwhois/core/v1}" + tag

tag_asn		  = ns("asn")
tag_net           = ns("net")
tag_org           = ns("org")
tag_poc           = ns("poc")
tag_orgHandle     = ns("orgHandle")
tag_netBlock      = ns("netBlock")
tag_type          = ns("type")
tag_startAddress  = ns("startAddress")
tag_endAddress    = ns("endAddress")
tag_startAsNumber = ns("startAsNumber")
tag_endAsNumber   = ns("endAsNumber")

def find(node, tag):
  return node.findtext(tag).strip()

def do_asn(node):
  asns.writerow((find(node, tag_orgHandle),
                 "%s-%s" % (find(node, tag_startAsNumber),
                            find(node, tag_endAsNumber))))

erx_table = {
  "AF" : "afrinic",
  "AP" : "apnic",
  "AR" : "arin",
  "AV" : "arin",
  "FX" : "afrinic",
  "LN" : "lacnic",
  "LX" : "lacnic",
  "PV" : "apnic",
  "PX" : "apnic",
  "RN" : "ripe",
  "RV" : "ripe",
  "RX" : "ripe" }

def do_net(node):
  handle = find(node, tag_orgHandle)
  for netblock in node.iter(tag_netBlock):
    tag = find(netblock, tag_type)
    startAddress = find(netblock, tag_startAddress)
    endAddress = find(netblock, tag_endAddress)
    if not startAddress.endswith(".000") and not startAddress.endswith(":0000"):
      continue
    if not endAddress.endswith(".255") and not endAddress.endswith(":FFFF"):
      continue
    if tag in ("DS", "DA", "IU"):
      prefixes.writerow((handle, "%s-%s" % (startAddress, endAddress)))
    elif tag in erx_table:
      erx.writerow((erx_table[tag], "%s-%s" % (startAddress, endAddress)))

dispatch = { tag_asn : do_asn, tag_net : do_net }

asns     = csv_writer("asns.csv")
prefixes = csv_writer("prefixes.csv")
erx      = csv_writer("erx.csv")

root = None

for event, node in lxml.etree.iterparse(sys.stdin):

  if root is None:
    root = node
    while root.getparent() is not None:
      root = root.getparent()

  if node.getparent() is root:

    if node.tag in dispatch:
      dispatch[node.tag](node)

    node.clear()
    while node.getprevious() is not None:
      del node.getparent()[0]

asns.close()
prefixes.close()
erx.close()