/*

  silcber.h

  Author: Pekka Riikonen <priikone@silcnet.org>

  Copyright (C) 2003 - 2007 Pekka Riikonen

  The contents of this file are subject to one of the Licenses specified 
  in the COPYING file;  You may not use this file except in compliance 
  with the License.

  The software distributed under the License is distributed on an "AS IS"
  basis, in the hope that it will be useful, but WITHOUT WARRANTY OF ANY
  KIND, either expressed or implied.  See the COPYING file for more
  information.

*/

/****h* silcasn1/BER Interface
 *
 * DESCRIPTION
 *
 * The Basic Encoding Rules (BER) is the data encoding format for the
 * ASN.1.  This interface provides routines for encoding and decoding
 * arbitraty BER data blocks.  Naturally, this interface can be used
 * to encode and decode DER blocks as well.  These routines does not
 * allocate any memory and have been optimized for general ASN.1 usage.
 *
 * References: ITU-T X.690
 * http://www.itu.int/ITU-T/studygroups/com17/languages/X690_0702.pdf
 *
 ***/

#ifndef SILCBER_H
#define SILCBER_H

/****d* silcasn1/SilcBerAPI/SilcBerClass
 *
 * NAME
 *
 *    typedef enum { ... } SilcBerClass;
 *
 * DESCRIPTION
 *
 *    Defines the BER classes.
 *
 ***/
typedef enum {
  SILC_BER_CLASS_UNIVERSAL       = 0x00,   /* Universal */
  SILC_BER_CLASS_APPLICATION     = 0x01,   /* Application */
  SILC_BER_CLASS_CONTEXT         = 0x02,   /* Context-specific */
  SILC_BER_CLASS_PRIVATE         = 0x03,   /* Private */
} SilcBerClass;
/***/

/****d* silcasn1/SilcBerAPI/SilcBerEncoding
 *
 * NAME
 *
 *    typedef enum { ... } SilcBerEncoding;
 *
 * DESCRIPTION
 *
 *    Defines the BER encoding type.
 *
 ***/
typedef enum {
  SILC_BER_ENC_PRIMITIVE         = 0x00,
  SILC_BER_ENC_CONSTRUCTED       = 0x01,
} SilcBerEncoding;
/***/

/****f* silcasn1/SilcBerAPI/silc_ber_encode
 *
 * SYNOPSIS
 *
 *    SilcBool
 *    silc_ber_encode(SilcBuffer ber, SilcBerClass ber_class,
 *                    SilcBerEncoding encoding, SilcUInt32 tag,
 *                    const unsigned char *data, SilcUInt32 data_len,
 *                    SilcBool indefinite);
 *
 * DESCRIPTION
 *
 *    Encodes a BER data block into the `ber', which must already have
 *    sufficient space allocated.  Caller can use silc_ber_encoded_len
 *    function to determine how much to allocate space before calling this
 *    function.  If the `indefinite' is TRUE then the BER block will not
 *    include the length of the data in the BER block.
 *
 ***/
SilcBool silc_ber_encode(SilcBuffer ber, SilcBerClass ber_class,
			 SilcBerEncoding encoding, SilcUInt32 tag,
			 const unsigned char *data, SilcUInt32 data_len,
			 SilcBool indefinite);

/****f* silcasn1/SilcBerAPI/silc_ber_decode
 *
 * SYNOPSIS
 *
 *    SilcBool
 *    silc_ber_decode(SilcBuffer ber, SilcBerClass *ber_class,
 *                    SilcBerEncoding *encoding, SilcUInt32 *tag,
 *                    const unsigned char **data, SilcUInt32 *data_len,
 *                    SilcBool *indefinite, SilcUInt32 *identifier_len);
 *
 * DESCRIPTION
 *
 *    Decodesa a BER data from the buffer `ber'.  Returns the class,
 *    encoding and the tag number for the BER data into `ber_class',
 *    `encoding' and `tag'.  A pointer to the start of the data area is
 *    returned into `data'.  If the length of the data is available from
 *    the BER data the length is returned into `data_len'.  If the
 *    `indefinite' is TRUE then the length found in `data_len' was found
 *    by finding end-of-contents octets from the BER data.  The
 *    `identifier_len' is the length of the BER header, and the length
 *    of the entire BER object is `identifier_len' + `data_len'.
 *
 ***/
SilcBool silc_ber_decode(SilcBuffer ber, SilcBerClass *ber_class,
			 SilcBerEncoding *encoding, SilcUInt32 *tag,
			 const unsigned char **data, SilcUInt32 *data_len,
			 SilcBool *indefinite, SilcUInt32 *identifier_len);

/****f* silcasn1/SilcBerAPI/silc_ber_encoded_len
 *
 * SYNOPSIS
 *
 *    SilcUInt32 silc_ber_encoded_len(SilcUInt32 tag, SilcUInt32 data_len,
 *                                    SilcBool indefinite);
 *
 * DESCRIPTION
 *
 *    Calculates the length of the encoded BER data object.  This utility
 *    function can be used to calculate how much to allocate space before
 *    encoding with silc_ber_encode.
 *
 ***/
SilcUInt32 silc_ber_encoded_len(SilcUInt32 tag, SilcUInt32 data_len,
				SilcBool indefinite);

#endif /* SILCBER_H */
