From 9fe8f72310cd683c8685de223ffae834e02c1ae4 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Tue, 20 Mar 2007 15:10:16 +0000 Subject: [PATCH] Add DER OID encoder/decoder --- libraries/liblber/decode.c | 34 +++++++++++++++++++++ libraries/liblber/encode.c | 61 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/libraries/liblber/decode.c b/libraries/liblber/decode.c index 7e1343f926..2dbd85602c 100644 --- a/libraries/liblber/decode.c +++ b/libraries/liblber/decode.c @@ -45,6 +45,40 @@ static ber_len_t ber_getnint LDAP_P(( ber_int_t *num, ber_len_t len )); +/* out->bv_len should be the buffer size on input */ +int +ber_decode_oid( BerValue *in, BerValue *out ) +{ + unsigned char *der = in->bv_val; + unsigned long val, val1; + int i, len; + char *ptr; + + assert( in != NULL ); + assert( out != NULL ); + + /* expands by 5/2, and we add dots - call it 3 */ + if ( !out->bv_val || out->bv_len < in->bv_len * 3 ) + return -1; + + val1 = der[0] / 40; + val = der[0] - val1 * 40; + + len = sprintf( out->bv_val, "%ld.%ld", val1, val ); + ptr = out->bv_val + len; + val = 0; + for ( i=1; ibv_len; i++ ) { + val = val << 7; + val |= der[i] & 0x7f; + if ( !( der[i] & 0x80 )) { + ptr += sprintf( ptr, ".%ld", val ); + val = 0; + } + } + out->bv_len = ptr - out->bv_val; + return 0; +} + /* return the tag - LBER_DEFAULT returned means trouble */ ber_tag_t ber_get_tag( BerElement *ber ) diff --git a/libraries/liblber/encode.c b/libraries/liblber/encode.c index 4272a5d9cf..741e269e31 100644 --- a/libraries/liblber/encode.c +++ b/libraries/liblber/encode.c @@ -177,6 +177,67 @@ ber_put_len( BerElement *ber, ber_len_t len, int nosos ) return rc == i ? i+1 : -1; } +/* out->bv_len should be the buffer size on input */ +int +ber_encode_oid( BerValue *in, BerValue *out ) +{ + unsigned char *der = out->bv_val; + unsigned long val, val1; + int i, len; + char *ptr, *end, *inend; + + assert( in != NULL ); + assert( out != NULL ); + + if ( !out->bv_val || out->bv_len < in->bv_len ) + return -1; + + /* OIDs must have at least two components */ + if ( sscanf( in->bv_val, "%ld.%ld", &val, &val1 ) != 2 ) + return -1; + + val *= 40; + val += val1; + + inend = in->bv_val + in->bv_len; + + ptr = strchr( in->bv_val, '.' ); + ptr = strchr( ptr+1, '.' ); + if ( ptr ) + ++ptr; + else + ptr = inend; + + for (;;) { + if ( !val ) { + *der++ = 0; + } else { + int hibit = 0; + i = sizeof(unsigned long) + 1; + len = i; + for (;val;) { + i--; + val1 = val & 0x7f; + val >>= 7; + der[i] = val1 | hibit; + hibit = 0x80; + } + if ( i ) { + len -= i; + memcpy( der, der+i, len ); + } + der += len; + } + if ( ptr >= inend ) break; + val = strtol( ptr, &end, 10 ); + if ( ptr == end ) break; + if ( *end && *end != '.' ) break; + ptr = end + 1; + } + out->bv_len = (char *)der - out->bv_val; + return 0; +} + static int ber_put_int_or_enum( BerElement *ber, -- 2.39.5