99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Use is subject to license terms.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * The contents of this file are subject to the Netscape Public License
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Version 1.0 (the "NPL"); you may not use this file except in
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * compliance with the NPL. You may obtain a copy of the NPL at
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * http://www.mozilla.org/NPL/
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Software distributed under the NPL is distributed on an "AS IS" basis,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * for the specific language governing rights and limitations under the
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * NPL.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * The Initial Developer of this code under the NPL is Netscape
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Communications Corporation. Portions created by Netscape are
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Copyright (C) 1998 Netscape Communications Corporation. All Rights
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Reserved.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Copyright (c) 1990 Regents of the University of Michigan.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * All rights reserved.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Redistribution and use in source and binary forms are permitted
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * provided that this notice is preserved and that due credit is given
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * to the University of Michigan at Ann Arbor. The name of the University
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * may not be used to endorse or promote products derived from this
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * software without specific prior written permission. This software
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * is provided ``as is'' without express or implied warranty.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/* decode.c - ber input decoding routines */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <strings.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <sys/types.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <netinet/in.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <inttypes.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <ber_der.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include "kmfber_int.h"
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic void
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysber_svecfree(char **vals)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int i;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (vals == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (i = 0; vals[i] != NULL; i++)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(vals[i]);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free((char *)vals);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Note: kmfber_get_tag() only uses the ber_end and ber_ptr elements of ber.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If that changes, the kmfber_peek_tag() and/or
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * kmfkmfber_skip_tag() implementations will need to be changed.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/* return the tag - KMFBER_DEFAULT returned means trouble */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic ber_tag_t
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyskmfber_get_tag(BerElement *ber)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys unsigned char xbyte;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber_tag_t tag;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *tagp;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int i;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (kmfber_read(ber, (char *)&xbyte, 1) != 1)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((xbyte & KMFBER_BIG_TAG_MASK) != KMFBER_BIG_TAG_MASK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return ((ber_uint_t)xbyte);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys tagp = (char *)&tag;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys tagp[0] = xbyte;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (i = 1; i < sizeof (ber_int_t); i++) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (kmfber_read(ber, (char *)&xbyte, 1) != 1)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys tagp[i] = xbyte;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (! (xbyte & KMFBER_MORE_TAG_MASK))
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* tag too big! */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (i == sizeof (ber_int_t))
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* want leading, not trailing 0's */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (tag >> (sizeof (ber_int_t)- i - 1));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Note: kmfber_skip_tag() only uses the ber_end and ber_ptr elements of ber.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If that changes, the implementation of kmfber_peek_tag() will need to
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * be changed.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysber_tag_t
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyskmfber_skip_tag(BerElement *ber, ber_len_t *len)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber_tag_t tag;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys unsigned char lc;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int noctets, diff;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys uint32_t netlen;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Any ber element looks like this: tag length contents.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Assuming everything's ok, we return the tag byte (we
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * can assume a single byte), and return the length in len.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Assumptions:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * 1) definite lengths
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * 2) primitive encodings used whenever possible
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * First, we read the tag.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((tag = kmfber_get_tag(ber)) == KMFBER_DEFAULT)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Next, read the length. The first byte contains the length of
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * the length. If bit 8 is set, the length is the long form,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * otherwise it's the short form. We don't allow a length that's
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * greater than what we can hold in an unsigned long.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *len = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys netlen = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (kmfber_read(ber, (char *)&lc, 1) != 1)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (lc & 0x80) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys noctets = (lc & 0x7f);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (noctets > sizeof (ber_uint_t))
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys diff = sizeof (ber_int_t) - noctets;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (kmfber_read(ber, (char *)&netlen + diff, noctets)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys != noctets)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *len = ntohl(netlen);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *len = lc;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (tag);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Note: Previously, we passed the "ber" parameter directly to
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * kmfber_skip_tag(), saving and restoring the ber_ptr element only.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * We now take advantage of the fact that the only ber structure
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * elements touched by kmfber_skip_tag() are ber_end and ber_ptr.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If that changes, this code must change too.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic ber_tag_t
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyskmfber_peek_tag(BerElement *ber, ber_len_t *len)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys BerElement bercopy;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys bercopy.ber_end = ber->ber_end;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys bercopy.ber_ptr = ber->ber_ptr;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (kmfber_skip_tag(&bercopy, len));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic int
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysber_getnint(BerElement *ber, ber_int_t *num, ber_slen_t len)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int i;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber_int_t value;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys unsigned char buffer[sizeof (ber_int_t)];
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * The tag and length have already been stripped off. We should
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * be sitting right before len bytes of 2's complement integer,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * ready to be read straight into an int. We may have to sign
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * extend after we read it in.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
ab8b4e5c888370036603c72719799620ea5c6b77Wyllys Ingersoll if (len > sizeof (buffer))
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (-1);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* read into the low-order bytes of netnum */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (kmfber_read(ber, (char *)buffer, len) != len)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (-1);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* This sets the required sign extension */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (len != 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys value = 0x80 & buffer[0] ? (-1) : 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys value = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (i = 0; i < len; i++)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys value = (value << 8) | buffer[i];
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *num = value;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (len);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic ber_tag_t
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyskmfber_get_int(BerElement *ber, ber_int_t *num)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber_tag_t tag;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber_len_t len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((tag = kmfber_skip_tag(ber, &len)) == KMFBER_DEFAULT)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * len is being demoted to a long here -- possible conversion error
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ber_getnint(ber, num, (int)len) != (ber_slen_t)len)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys else
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (tag);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic ber_tag_t
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyskmfber_get_stringb(BerElement *ber, char *buf, ber_len_t *len)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber_len_t datalen;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber_tag_t tag;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#ifdef STR_TRANSLATION
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *transbuf;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#endif /* STR_TRANSLATION */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((tag = kmfber_skip_tag(ber, &datalen)) == KMFBER_DEFAULT)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (datalen > (*len - 1))
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * datalen is being demoted to a long here -- possible conversion error
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (kmfber_read(ber, buf, datalen) != (ber_slen_t)datalen)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys buf[datalen] = '\0';
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#ifdef STR_TRANSLATION
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (datalen > 0 && (ber->ber_options & KMFBER_OPT_TRANSLATE_STRINGS)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys != 0 && ber->ber_decode_translate_proc != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys transbuf = buf;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ++datalen;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((*(ber->ber_decode_translate_proc))(&transbuf, &datalen,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys 0) != 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (datalen > *len) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(transbuf);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memmove(buf, transbuf, datalen);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(transbuf);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys --datalen;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#endif /* STR_TRANSLATION */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *len = datalen;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (tag);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic ber_tag_t
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyskmfber_get_stringa(BerElement *ber, char **buf)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber_len_t datalen;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber_tag_t tag;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((tag = kmfber_skip_tag(ber, &datalen)) == KMFBER_DEFAULT)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((*buf = (char *)malloc((size_t)datalen + 1)) == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * datalen is being demoted to a long here -- possible conversion error
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (kmfber_read(ber, *buf, datalen) != (ber_slen_t)datalen)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (*buf)[datalen] = '\0';
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (tag);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysber_tag_t
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysber_get_oid(BerElement *ber, struct berval *oid)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber_len_t len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber_tag_t tag;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((tag = kmfber_skip_tag(ber, &len)) != 0x06) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((oid->bv_val = (char *)malloc((size_t)len + 1)) == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys oid->bv_len = len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (kmfber_read(ber, oid->bv_val, oid->bv_len) !=
d00756ccb34596a328f8a15d1965da5412d366d0wyllys (ber_slen_t)oid->bv_len)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (tag);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysber_tag_t
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysber_get_bigint(BerElement *ber, struct berval **bv)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber_len_t len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber_tag_t tag;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((*bv = (struct berval *)malloc(sizeof (struct berval)))
d00756ccb34596a328f8a15d1965da5412d366d0wyllys == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys (*bv)->bv_len = 0;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys (*bv)->bv_val = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((tag = kmfber_skip_tag(ber, &len)) != BER_INTEGER) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (((*bv)->bv_val = (char *)malloc((size_t)len + 1))
d00756ccb34596a328f8a15d1965da5412d366d0wyllys == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * len is being demoted to a long here -- possible conversion error
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (kmfber_read(ber, (*bv)->bv_val, len) != (ber_slen_t)len)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (*bv)->bv_len = len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll /* If DER encoding, strip leading 0's if high-order bit is set */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ber->ber_options & KMFBER_OPT_USE_DER) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *p = (*bv)->bv_val;
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll while ((*p == 0x00) && ((*bv)->bv_len > 0) && (p[1] & 0x80)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys p++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (*bv)->bv_len--;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Shift the buffer to the beginning of the allocated space
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * so it can be properly freed later.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((p > (*bv)->bv_val) && ((*bv)->bv_len > 0))
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) bcopy(p, (*bv)->bv_val, (*bv)->bv_len);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (tag);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic ber_tag_t
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyskmfber_get_stringal(BerElement *ber, struct berval **bv)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber_len_t len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber_tag_t tag;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((*bv = (struct berval *)malloc(sizeof (struct berval)))
d00756ccb34596a328f8a15d1965da5412d366d0wyllys == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((tag = kmfber_skip_tag(ber, &len)) == KMFBER_DEFAULT) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (((*bv)->bv_val = (char *)malloc((size_t)len + 1))
d00756ccb34596a328f8a15d1965da5412d366d0wyllys == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * len is being demoted to a long here -- possible conversion error
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (kmfber_read(ber, (*bv)->bv_val, len) != (ber_slen_t)len)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ((*bv)->bv_val)[len] = '\0';
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (*bv)->bv_len = len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (tag);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic ber_tag_t
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyskmfber_get_bitstringa(BerElement *ber, char **buf, ber_len_t *blen)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber_len_t datalen;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber_tag_t tag;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys unsigned char unusedbits;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((tag = kmfber_skip_tag(ber, &datalen)) == KMFBER_DEFAULT)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((*buf = (char *)malloc((size_t)datalen - 1)) == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (kmfber_read(ber, (char *)&unusedbits, 1) != 1)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Subtract 1 for the unused bits */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys datalen--;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * datalen is being demoted to a long here -- possible conversion error
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (kmfber_read(ber, *buf, datalen) != (ber_slen_t)datalen)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *blen = datalen * 8 - unusedbits;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (tag);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic ber_tag_t
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyskmfber_get_null(BerElement *ber)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber_len_t len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber_tag_t tag;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((tag = kmfber_skip_tag(ber, &len)) == KMFBER_DEFAULT)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (len != 0)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_DEFAULT);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (tag);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic ber_tag_t
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyskmfber_get_boolean(BerElement *ber, int *boolval)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber_int_t longbool;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int rc;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rc = kmfber_get_int(ber, &longbool);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *boolval = longbool;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rc);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysber_tag_t
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyskmfber_first_element(BerElement *ber, ber_len_t *len, char **last)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* skip the sequence header, use the len to mark where to stop */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (kmfber_skip_tag(ber, len) == KMFBER_DEFAULT) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_ERROR);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *last = ber->ber_ptr + *len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (*last == ber->ber_ptr) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_END_OF_SEQORSET);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (kmfber_peek_tag(ber, len));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysber_tag_t
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyskmfber_next_element(BerElement *ber, ber_len_t *len, char *last)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ber->ber_ptr == last) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMFBER_END_OF_SEQORSET);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (kmfber_peek_tag(ber, len));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysvoid
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyskmfber_bvfree(struct berval *bv)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (bv != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (bv->bv_val != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(bv->bv_val);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free((char *)bv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysvoid
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyskmfber_bvecfree(struct berval **bv)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int i;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (bv != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (i = 0; bv[i] != NULL; i++) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys kmfber_bvfree(bv[i]);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free((char *)bv);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/* VARARGS */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysber_tag_t
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyskmfber_scanf(BerElement *ber, const char *fmt, ...)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys va_list ap;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *last, *p;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *s, **ss, ***sss;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys struct berval ***bv, **bvp, *bval;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int *i, j;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber_slen_t *l;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber_int_t rc, tag, *b_int;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber_tag_t *t;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber_len_t len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys size_t array_size;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys va_start(ap, fmt);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (rc = 0, p = (char *)fmt; *p && rc != KMFBER_DEFAULT; p++) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys switch (*p) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'a': /* octet string - allocate storage as needed */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ss = va_arg(ap, char **);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rc = kmfber_get_stringa(ber, ss);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'b': /* boolean */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys i = va_arg(ap, int *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rc = kmfber_get_boolean(ber, i);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'D': /* Object ID */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys bval = va_arg(ap, struct berval *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rc = ber_get_oid(ber, bval);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'e': /* enumerated */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'i': /* int */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys b_int = va_arg(ap, ber_int_t *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rc = kmfber_get_int(ber, b_int);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'l': /* length of next item */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys l = va_arg(ap, ber_slen_t *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rc = kmfber_peek_tag(ber, (ber_len_t *)l);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'n': /* null */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rc = kmfber_get_null(ber);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 's': /* octet string - in a buffer */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys s = va_arg(ap, char *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys l = va_arg(ap, ber_slen_t *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rc = kmfber_get_stringb(ber, s, (ber_len_t *)l);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'o': /* octet string in a supplied berval */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys bval = va_arg(ap, struct berval *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) kmfber_peek_tag(ber, &bval->bv_len);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rc = kmfber_get_stringa(ber, &bval->bv_val);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'I': /* variable length Integer */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Treat INTEGER same as an OCTET string, but ignore the tag */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys bvp = va_arg(ap, struct berval **);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rc = ber_get_bigint(ber, bvp);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'O': /* octet string - allocate & include length */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys bvp = va_arg(ap, struct berval **);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rc = kmfber_get_stringal(ber, bvp);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'B': /* bit string - allocate storage as needed */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ss = va_arg(ap, char **);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys l = va_arg(ap, ber_slen_t *); /* for length, in bits */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rc = kmfber_get_bitstringa(ber, ss, (ber_len_t *)l);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 't': /* tag of next item */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys t = va_arg(ap, ber_tag_t *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *t = kmfber_peek_tag(ber, &len);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rc = (ber_int_t)(*t);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'T': /* skip tag of next item */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys t = va_arg(ap, ber_tag_t *);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *t = kmfber_skip_tag(ber, &len);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rc = (ber_int_t)(*t);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'v': /* sequence of strings */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys sss = va_arg(ap, char ***);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (sss == NULL)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *sss = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys j = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys array_size = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (tag = kmfber_first_element(ber, &len, &last);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys (tag != KMFBER_DEFAULT &&
d00756ccb34596a328f8a15d1965da5412d366d0wyllys tag != KMFBER_END_OF_SEQORSET &&
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rc != KMFBER_DEFAULT);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys tag = kmfber_next_element(ber, &len, last)) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (*sss == NULL) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys /* Make room for at least 15 strings */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys *sss = (char **)malloc(16 * sizeof (char *));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys array_size = 16;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys } else {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if ((size_t)(j+2) > array_size) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys /* We'v overflowed our buffer */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys *sss = (char **)realloc(*sss,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys (array_size * 2) * sizeof (char *));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys array_size = array_size * 2;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rc = kmfber_get_stringa(ber, &((*sss)[j]));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys j++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (rc != KMFBER_DEFAULT && tag != KMFBER_END_OF_SEQORSET) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rc = KMFBER_DEFAULT;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (j > 0)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys (*sss)[j] = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'V': /* sequence of strings + lengths */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys bv = va_arg(ap, struct berval ***);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *bv = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys j = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (tag = kmfber_first_element(ber, &len, &last);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys (tag != KMFBER_DEFAULT &&
d00756ccb34596a328f8a15d1965da5412d366d0wyllys tag != KMFBER_END_OF_SEQORSET &&
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rc != KMFBER_DEFAULT);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys tag = kmfber_next_element(ber, &len, last)) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (*bv == NULL) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys *bv = (struct berval **)malloc(
d00756ccb34596a328f8a15d1965da5412d366d0wyllys 2 * sizeof (struct berval *));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys } else {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys *bv = (struct berval **)realloc(*bv,
d00756ccb34596a328f8a15d1965da5412d366d0wyllys (j + 2) * sizeof (struct berval *));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rc = kmfber_get_stringal(ber, &((*bv)[j]));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys j++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rc != KMFBER_DEFAULT &&
d00756ccb34596a328f8a15d1965da5412d366d0wyllys tag != KMFBER_END_OF_SEQORSET) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rc = KMFBER_DEFAULT;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (j > 0)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys (*bv)[j] = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case 'x': /* skip the next element - whatever it is */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((rc = kmfber_skip_tag(ber, &len)) == KMFBER_DEFAULT)
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ber->ber_ptr += len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case '{': /* begin sequence */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case '[': /* begin set */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (*(p + 1) != 'v' && *(p + 1) != 'V')
d00756ccb34596a328f8a15d1965da5412d366d0wyllys rc = kmfber_skip_tag(ber, &len);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case '}': /* end sequence */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys case ']': /* end set */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
d00756ccb34596a328f8a15d1965da5412d366d0wyllys default:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys rc = KMFBER_DEFAULT;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys va_end(ap);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rc == KMFBER_DEFAULT) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys va_start(ap, fmt);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (p--; fmt < p && *fmt; fmt++) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys switch (*fmt) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case 'a': /* octet string - allocate storage as needed */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys ss = va_arg(ap, char **);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (ss != NULL && *ss != NULL) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys free(*ss);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys *ss = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case 'b': /* boolean */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys i = va_arg(ap, int *);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case 'e': /* enumerated */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case 'i': /* int */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys l = va_arg(ap, ber_slen_t *);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case 'l': /* length of next item */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys l = va_arg(ap, ber_slen_t *);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case 'n': /* null */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case 's': /* octet string - in a buffer */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys s = va_arg(ap, char *);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys l = va_arg(ap, ber_slen_t *);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case 'o': /* octet string in a supplied berval */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys bval = va_arg(ap, struct berval *);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (bval->bv_val) free(bval->bv_val);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys (void) memset(bval, 0, sizeof (struct berval));
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case 'O': /* octet string - allocate & include length */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys bvp = va_arg(ap, struct berval **);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmfber_bvfree(*bvp);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys bvp = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case 'B': /* bit string - allocate storage as needed */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys ss = va_arg(ap, char **);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys l = va_arg(ap, ber_slen_t *); /* for length, in bits */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (ss != NULL && *ss != NULL) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys free(*ss);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys *ss = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case 't': /* tag of next item */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys t = va_arg(ap, ber_tag_t *);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case 'T': /* skip tag of next item */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys t = va_arg(ap, ber_tag_t *);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case 'v': /* sequence of strings */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys sss = va_arg(ap, char ***);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys if (sss != NULL && *sss != NULL) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys ber_svecfree(*sss);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys *sss = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case 'V': /* sequence of strings + lengths */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys bv = va_arg(ap, struct berval ***);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys kmfber_bvecfree(*bv);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys *bv = NULL;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case 'x': /* skip the next element - whatever it is */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case '{': /* begin sequence */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case '[': /* begin set */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case '}': /* end sequence */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys case ']': /* end set */
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys default:
d00756ccb34596a328f8a15d1965da5412d366d0wyllys break;
d00756ccb34596a328f8a15d1965da5412d366d0wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } /* for */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys va_end(ap);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } /* if */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (rc);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstruct berval *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyskmfber_bvdup(const struct berval *bv)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys struct berval *new;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((new = (struct berval *)malloc(sizeof (struct berval)))
d00756ccb34596a328f8a15d1965da5412d366d0wyllys == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (bv->bv_val == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys new->bv_val = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys new->bv_len = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((new->bv_val = (char *)malloc(bv->bv_len + 1))
d00756ccb34596a328f8a15d1965da5412d366d0wyllys == NULL) {
d00756ccb34596a328f8a15d1965da5412d366d0wyllys return (NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memmove(new->bv_val, bv->bv_val, (size_t)bv->bv_len);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys new->bv_val[bv->bv_len] = '\0';
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys new->bv_len = bv->bv_len;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (new);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}