Commit 822f6cda authored by Brian Wellington's avatar Brian Wellington

Created isc_base64_to{text,buffer} and removed the static versions

from lib/dns/rdata.c.
parent 71b306bf
......@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: rdata.c,v 1.45 1999/05/17 15:40:39 marka Exp $ */
/* $Id: rdata.c,v 1.46 1999/05/18 17:46:59 bwelling Exp $ */
#include <config.h>
......@@ -23,6 +23,7 @@
#include <stdio.h>
#include <time.h>
#include <isc/base64.h>
#include <isc/buffer.h>
#include <isc/lex.h>
#include <isc/assertions.h>
......@@ -72,11 +73,6 @@ static dns_result_t mem_tobuffer(isc_buffer_t *target, void *base,
static int compare_region(isc_region_t *r1, isc_region_t *r2);
static int hexvalue(char value);
static int decvalue(char value);
static dns_result_t base64_totext(isc_region_t *source,
isc_buffer_t *target);
static dns_result_t base64_tobuffer(isc_lex_t *lexer,
isc_buffer_t *target,
int length);
static dns_result_t time_totext(unsigned long value,
isc_buffer_t *target);
static dns_result_t time_tobuffer(char *source, isc_buffer_t *target);
......@@ -987,113 +983,6 @@ decvalue(char value) {
return (s - decdigits);
}
static const char base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
static dns_result_t
base64_totext(isc_region_t *source, isc_buffer_t *target) {
char buf[5];
int loops = 0;
memset(buf, 0, sizeof buf);
RETERR(str_totext("( " /*)*/, target));
while (source->length > 2) {
buf[0] = base64[(source->base[0]>>2)&0x3f];
buf[1] = base64[((source->base[0]<<4)&0x30)|
((source->base[1]>>4)&0x0f)];
buf[2] = base64[((source->base[1]<<2)&0x3c)|
((source->base[2]>>6)&0x03)];
buf[3] = base64[source->base[2]&0x3f];
RETERR(str_totext(buf, target));
isc_region_consume(source, 3);
if (source->length != 0 && ++loops == 15) {
loops = 0;
RETERR(str_totext(" ", target));
}
}
if (source->length == 2) {
buf[0] = base64[(source->base[0]>>2)&0x3f];
buf[1] = base64[((source->base[0]<<4)&0x30)|
((source->base[1]>>4)&0x0f)];
buf[2] = base64[((source->base[1]<<2)&0x3c)];
buf[3] = '=';
RETERR(str_totext(buf, target));
} else if (source->length == 1) {
buf[0] = base64[(source->base[0]>>2)&0x3f];
buf[1] = base64[((source->base[0]<<4)&0x30)];
buf[2] = buf[3] = '=';
RETERR(str_totext(buf, target));
}
RETERR(str_totext(" )", target));
return (DNS_R_SUCCESS);
}
static dns_result_t
base64_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) {
int digits = 0;
isc_textregion_t *tr;
int val[4];
unsigned char buf[3];
int seen_end = 0;
unsigned int i;
isc_token_t token;
char *s;
int n;
while (!seen_end && (length != 0)) {
if (length > 0)
RETERR(gettoken(lexer, &token, isc_tokentype_string,
ISC_FALSE));
else
RETERR(gettoken(lexer, &token, isc_tokentype_string,
ISC_TRUE));
if (token.type != isc_tokentype_string)
break;
tr = &token.value.as_textregion;
for (i = 0 ;i < tr->length; i++) {
if (seen_end)
return (DNS_R_BADBASE64);
if ((s = strchr(base64, tr->base[i])) == NULL)
return (DNS_R_BADBASE64);
val[digits++] = s - base64;
if (digits == 4) {
if (val[0] == 64 || val[1] == 64)
return (DNS_R_BADBASE64);
if (val[2] == 64 && val[3] != 64)
return (DNS_R_BADBASE64);
n = (val[2] == 64) ? 1 :
(val[3] == 64) ? 2 : 3;
if (n != 3) {
seen_end = 1;
if (val[2] == 64)
val[2] = 0;
if (val[3] == 64)
val[3] = 0;
}
buf[0] = (val[0]<<2)|(val[1]>>4);
buf[1] = (val[1]<<4)|(val[2]>>2);
buf[2] = (val[2]<<6)|(val[3]);
RETERR(mem_tobuffer(target, buf, n));
if (length >= 0) {
if (n > length)
return (DNS_R_BADBASE64);
else
length -= n;
}
digits = 0;
}
}
}
if (length < 0 && !seen_end)
isc_lex_ungettoken(lexer, &token);
if (length > 0)
return (DNS_R_UNEXPECTEDEND);
if (digits != 0)
return (DNS_R_BADBASE64);
return (DNS_R_SUCCESS);
}
static int days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
static dns_result_t
......
......@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: tsig_250.c,v 1.9 1999/05/07 03:24:05 marka Exp $ */
/* $Id: tsig_250.c,v 1.10 1999/05/18 17:46:59 bwelling Exp $ */
/* draft-ietf-dnsind-tsig-07.txt */
......@@ -68,7 +68,7 @@ fromtext_any_tsig(dns_rdataclass_t class, dns_rdatatype_t type,
RETERR(uint16_tobuffer(token.value.as_ulong, target));
/* Signature */
RETERR(base64_tobuffer(lexer, target, token.value.as_ulong));
RETERR(isc_base64_tobuffer(lexer, target, token.value.as_ulong));
/* Original ID */
RETERR(gettoken(lexer, &token, isc_tokentype_number, ISC_FALSE));
......@@ -89,7 +89,7 @@ fromtext_any_tsig(dns_rdataclass_t class, dns_rdatatype_t type,
RETERR(uint16_tobuffer(token.value.as_ulong, target));
/* Other Data */
return (base64_tobuffer(lexer, target, token.value.as_ulong));
return (isc_base64_tobuffer(lexer, target, token.value.as_ulong));
}
static dns_result_t
......@@ -149,7 +149,7 @@ totext_any_tsig(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target) {
REQUIRE(n <= sr.length);
sigr = sr;
sigr.length = n;
RETERR(base64_totext(&sigr, target));
RETERR(isc_base64_totext(&sigr, target));
RETERR(str_totext(" ", target));
isc_region_consume(&sr, n);
......@@ -172,7 +172,7 @@ totext_any_tsig(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target) {
RETERR(str_totext(buf, target));
/* Other */
return (base64_totext(&sr, target));
return (isc_base64_totext(&sr, target));
}
static dns_result_t
......
......@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: cert_37.c,v 1.7 1999/05/07 03:24:06 marka Exp $ */
/* $Id: cert_37.c,v 1.8 1999/05/18 17:46:59 bwelling Exp $ */
/* draft-ietf-dnssec-certs-04.txt */
......@@ -70,7 +70,7 @@ fromtext_cert(dns_rdataclass_t class, dns_rdatatype_t type,
}
RETERR(mem_tobuffer(target, &secalg, 1));
return (base64_tobuffer(lexer, target, -1));
return (isc_base64_tobuffer(lexer, target, -1));
}
static dns_result_t
......@@ -103,7 +103,7 @@ totext_cert(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target) {
isc_region_consume(&sr, 1);
/* cert */
return (base64_totext(&sr, target));
return (isc_base64_totext(&sr, target));
}
static dns_result_t
......
......@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: key_25.c,v 1.5 1999/05/07 03:24:07 marka Exp $ */
/* $Id: key_25.c,v 1.6 1999/05/18 17:46:59 bwelling Exp $ */
/* RFC 2065 */
......@@ -59,7 +59,7 @@ fromtext_key(dns_rdataclass_t class, dns_rdatatype_t type,
if ((flags & 0xc000) == 0xc000)
return (DNS_R_SUCCESS);
return (base64_tobuffer(lexer, target, -1));
return (isc_base64_tobuffer(lexer, target, -1));
}
static dns_result_t
......@@ -98,7 +98,7 @@ totext_key(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target) {
/* key */
RETERR(str_totext(" ", target));
return (base64_totext(&sr, target));
return (isc_base64_totext(&sr, target));
}
static dns_result_t
......
......@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: sig_24.c,v 1.11 1999/05/07 03:24:11 marka Exp $ */
/* $Id: sig_24.c,v 1.12 1999/05/18 17:46:59 bwelling Exp $ */
/* RFC 2065 */
......@@ -92,7 +92,7 @@ fromtext_sig(dns_rdataclass_t class, dns_rdatatype_t type,
RETERR(dns_name_fromtext(&name, &buffer, origin, downcase, target));
/* sig */
return (base64_tobuffer(lexer, target, -1));
return (isc_base64_tobuffer(lexer, target, -1));
}
static dns_result_t
......@@ -168,7 +168,7 @@ totext_sig(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target) {
RETERR(str_totext(" ", target));
/* sig */
return (base64_totext(&sr, target));
return (isc_base64_totext(&sr, target));
}
static dns_result_t
......
......@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: tkey_249.c,v 1.9 1999/05/07 03:24:12 marka Exp $ */
/* $Id: tkey_249.c,v 1.10 1999/05/18 17:46:59 bwelling Exp $ */
/* draft-ietf-dnssec-tkey-01.txt */
......@@ -80,7 +80,7 @@ fromtext_tkey(dns_rdataclass_t class, dns_rdatatype_t type,
RETERR(uint16_tobuffer(token.value.as_ulong, target));
/* Signature */
RETERR(base64_tobuffer(lexer, target, token.value.as_ulong));
RETERR(isc_base64_tobuffer(lexer, target, token.value.as_ulong));
/* Other Len */
RETERR(gettoken(lexer, &token, isc_tokentype_number, ISC_FALSE));
......@@ -89,7 +89,7 @@ fromtext_tkey(dns_rdataclass_t class, dns_rdatatype_t type,
RETERR(uint16_tobuffer(token.value.as_ulong, target));
/* Other Data */
return (base64_tobuffer(lexer, target, token.value.as_ulong));
return (isc_base64_tobuffer(lexer, target, token.value.as_ulong));
}
static dns_result_t
......@@ -153,7 +153,7 @@ totext_tkey(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target) {
REQUIRE(n <= sr.length);
sigr = sr;
sigr.length = n;
RETERR(base64_totext(&sigr, target));
RETERR(isc_base64_totext(&sigr, target));
RETERR(str_totext(" ", target));
isc_region_consume(&sr, n);
......@@ -164,7 +164,7 @@ totext_tkey(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target) {
RETERR(str_totext(buf, target));
/* Other */
return (base64_totext(&sr, target));
return (isc_base64_totext(&sr, target));
}
static dns_result_t
......
......@@ -26,8 +26,9 @@ CDEFINES =
CWARNINGS =
OBJS = @ISC_EXTRA_OBJS@ \
assertions.o buffer.o error.o heap.o lex.o mem.o result.o \
rwlock.o symtab.o str.o event.o task.o timer.o version.o \
assertions.o base64.o buffer.o error.o heap.o lex.o mem.o \
result.o rwlock.o symtab.o str.o event.o task.o timer.o \
version.o \
unix/app.o unix/time.o unix/stdtime.o unix/socket.o \
pthreads/condition.o
......
/*
* Copyright (C) 1998, 1999 Internet Software Consortium.
*
* 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM 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.
*/
/* $Id: base64.c,v 1.1 1999/05/18 17:46:58 bwelling Exp $ */
#include <config.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <isc/base64.h>
#include <isc/buffer.h>
#include <isc/lex.h>
#include <isc/assertions.h>
#include <isc/error.h>
#include <isc/region.h>
#define RETERR(x) do { \
isc_result_t __r = (x); \
if (__r != ISC_R_SUCCESS) \
return (__r); \
} while (0)
/* These static functions are also present in lib/dns/rdata.c. I'm not
* sure where they should go. -- bwelling
*/
static isc_result_t str_totext(char *source, isc_buffer_t *target);
static isc_result_t gettoken(isc_lex_t *lexer, isc_token_t *token,
isc_tokentype_t expect, isc_boolean_t eol);
static isc_result_t mem_tobuffer(isc_buffer_t *target, void *base,
unsigned int length);
static const char base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
isc_result_t
isc_base64_totext(isc_region_t *source, isc_buffer_t *target) {
char buf[5];
int loops = 0;
memset(buf, 0, sizeof buf);
RETERR(str_totext("( " /*)*/, target));
while (source->length > 2) {
buf[0] = base64[(source->base[0]>>2)&0x3f];
buf[1] = base64[((source->base[0]<<4)&0x30)|
((source->base[1]>>4)&0x0f)];
buf[2] = base64[((source->base[1]<<2)&0x3c)|
((source->base[2]>>6)&0x03)];
buf[3] = base64[source->base[2]&0x3f];
RETERR(str_totext(buf, target));
isc_region_consume(source, 3);
if (source->length != 0 && ++loops == 15) {
loops = 0;
RETERR(str_totext(" ", target));
}
}
if (source->length == 2) {
buf[0] = base64[(source->base[0]>>2)&0x3f];
buf[1] = base64[((source->base[0]<<4)&0x30)|
((source->base[1]>>4)&0x0f)];
buf[2] = base64[((source->base[1]<<2)&0x3c)];
buf[3] = '=';
RETERR(str_totext(buf, target));
} else if (source->length == 1) {
buf[0] = base64[(source->base[0]>>2)&0x3f];
buf[1] = base64[((source->base[0]<<4)&0x30)];
buf[2] = buf[3] = '=';
RETERR(str_totext(buf, target));
}
RETERR(str_totext(" )", target));
return (ISC_R_SUCCESS);
}
isc_result_t
isc_base64_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) {
int digits = 0;
isc_textregion_t *tr;
int val[4];
unsigned char buf[3];
int seen_end = 0;
unsigned int i;
isc_token_t token;
char *s;
int n;
while (!seen_end && (length != 0)) {
if (length > 0)
RETERR(gettoken(lexer, &token, isc_tokentype_string,
ISC_FALSE));
else
RETERR(gettoken(lexer, &token, isc_tokentype_string,
ISC_TRUE));
if (token.type != isc_tokentype_string)
break;
tr = &token.value.as_textregion;
for (i = 0 ;i < tr->length; i++) {
if (seen_end)
return (ISC_R_BADBASE64);
if ((s = strchr(base64, tr->base[i])) == NULL)
return (ISC_R_BADBASE64);
val[digits++] = s - base64;
if (digits == 4) {
if (val[0] == 64 || val[1] == 64)
return (ISC_R_BADBASE64);
if (val[2] == 64 && val[3] != 64)
return (ISC_R_BADBASE64);
n = (val[2] == 64) ? 1 :
(val[3] == 64) ? 2 : 3;
if (n != 3) {
seen_end = 1;
if (val[2] == 64)
val[2] = 0;
if (val[3] == 64)
val[3] = 0;
}
buf[0] = (val[0]<<2)|(val[1]>>4);
buf[1] = (val[1]<<4)|(val[2]>>2);
buf[2] = (val[2]<<6)|(val[3]);
RETERR(mem_tobuffer(target, buf, n));
if (length >= 0) {
if (n > length)
return (ISC_R_BADBASE64);
else
length -= n;
}
digits = 0;
}
}
}
if (length < 0 && !seen_end)
isc_lex_ungettoken(lexer, &token);
if (length > 0)
return (ISC_R_UNEXPECTEDEND);
if (digits != 0)
return (ISC_R_BADBASE64);
return (ISC_R_SUCCESS);
}
static isc_result_t
str_totext(char *source, isc_buffer_t *target) {
unsigned int l;
isc_region_t region;
isc_buffer_available(target, &region);
l = strlen(source);
if (l > region.length)
return (ISC_R_NOSPACE);
memcpy(region.base, source, l);
isc_buffer_add(target, l);
return (ISC_R_SUCCESS);
}
static isc_result_t
mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) {
isc_region_t tr;
isc_buffer_available(target, &tr);
if (length > tr.length)
return (ISC_R_NOSPACE);
memcpy(tr.base, base, length);
isc_buffer_add(target, length);
return (ISC_R_SUCCESS);
}
static isc_result_t
gettoken(isc_lex_t *lexer, isc_token_t *token, isc_tokentype_t expect,
isc_boolean_t eol)
{
unsigned int options = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF |
ISC_LEXOPT_DNSMULTILINE;
isc_result_t result;
if (expect == isc_tokentype_qstring)
options |= ISC_LEXOPT_QSTRING;
else if (expect == isc_tokentype_number)
options |= ISC_LEXOPT_NUMBER;
result = isc_lex_gettoken(lexer, options, token);
result = isc_lex_gettoken(lexer, options, token);
switch (result) {
case ISC_R_SUCCESS:
break;
case ISC_R_NOMEMORY:
return (ISC_R_NOMEMORY);
case ISC_R_NOSPACE:
return (ISC_R_NOSPACE);
default:
UNEXPECTED_ERROR(__FILE__, __LINE__,
"isc_lex_gettoken() failed: %s\n",
isc_result_totext(result));
return (ISC_R_UNEXPECTED);
}
if (eol && ((token->type == isc_tokentype_eol) ||
(token->type == isc_tokentype_eof)))
return (ISC_R_SUCCESS);
if (token->type == isc_tokentype_string &&
expect == isc_tokentype_qstring)
return (ISC_R_SUCCESS);
if (token->type != expect) {
isc_lex_ungettoken(lexer, token);
if (token->type == isc_tokentype_eol ||
token->type == isc_tokentype_eof)
return (ISC_R_UNEXPECTEDEND);
return (ISC_R_UNEXPECTEDTOKEN);
}
return (ISC_R_SUCCESS);
}
/*
* Copyright (C) 1999 Internet Software Consortium.
*
* 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM 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.
*/
/* $Id: base64.h,v 1.1 1999/05/18 17:46:59 bwelling Exp $ */
#ifndef ISC_BASE64_H
#define ISC_BASE64_H 1
#include <isc/buffer.h>
#include <isc/lang.h>
#include <isc/lex.h>
#include <isc/region.h>
#include <isc/result.h>
#include <isc/types.h>
ISC_LANG_BEGINDECLS
/***
*** Functions
***/
/* Convert data into base64 encoded text.
*
* Requires:
* "source" is a region containing binary data
* "target" is a text buffer containing available space
*
* Ensures:
* target will contain the base64 encoded version of the data
* in source. The "used" pointer in target will be advanced as
* necessary.
*/
isc_result_t
isc_base64_totext(isc_region_t *source, isc_buffer_t *target);
/* Convert base64 encoded text into data.
*
* Requires:
* "lex" is a valid lexer context
* "target" is a binary buffer containing binary data
* "length" is an integer
*
* Ensures:
* target will contain the data represented by the base64 encoded
* string parsed by the lexer. No more than length bytes will be read,
* if length is positive. The "used" pointer in target will be
* advanced as necessary.
*/
isc_result_t
isc_base64_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length);
ISC_LANG_ENDDECLS
#endif /* ISC_BASE64_H */
......@@ -55,7 +55,9 @@ typedef unsigned int isc_result_t;