michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: * Support for encoding/decoding of ASN.1 using BER/DER (Basic/Distinguished michael@0: * Encoding Rules). The routines are found in and used extensively by the michael@0: * security library, but exported for other use. michael@0: */ michael@0: michael@0: #ifndef _SECASN1_H_ michael@0: #define _SECASN1_H_ michael@0: michael@0: #include "utilrename.h" michael@0: #include "plarena.h" michael@0: michael@0: #include "seccomon.h" michael@0: #include "secasn1t.h" michael@0: michael@0: michael@0: /************************************************************************/ michael@0: SEC_BEGIN_PROTOS michael@0: michael@0: /* michael@0: * XXX These function prototypes need full, explanatory comments. michael@0: */ michael@0: michael@0: /* michael@0: ** Decoding. michael@0: */ michael@0: michael@0: extern SEC_ASN1DecoderContext *SEC_ASN1DecoderStart(PLArenaPool *pool, michael@0: void *dest, michael@0: const SEC_ASN1Template *t); michael@0: michael@0: /* XXX char or unsigned char? */ michael@0: extern SECStatus SEC_ASN1DecoderUpdate(SEC_ASN1DecoderContext *cx, michael@0: const char *buf, michael@0: unsigned long len); michael@0: michael@0: extern SECStatus SEC_ASN1DecoderFinish(SEC_ASN1DecoderContext *cx); michael@0: michael@0: /* Higher level code detected an error, abort the rest of the processing */ michael@0: extern void SEC_ASN1DecoderAbort(SEC_ASN1DecoderContext *cx, int error); michael@0: michael@0: extern void SEC_ASN1DecoderSetFilterProc(SEC_ASN1DecoderContext *cx, michael@0: SEC_ASN1WriteProc fn, michael@0: void *arg, PRBool no_store); michael@0: michael@0: extern void SEC_ASN1DecoderClearFilterProc(SEC_ASN1DecoderContext *cx); michael@0: michael@0: extern void SEC_ASN1DecoderSetNotifyProc(SEC_ASN1DecoderContext *cx, michael@0: SEC_ASN1NotifyProc fn, michael@0: void *arg); michael@0: michael@0: extern void SEC_ASN1DecoderClearNotifyProc(SEC_ASN1DecoderContext *cx); michael@0: michael@0: extern SECStatus SEC_ASN1Decode(PLArenaPool *pool, void *dest, michael@0: const SEC_ASN1Template *t, michael@0: const char *buf, long len); michael@0: michael@0: /* Both classic ASN.1 and QuickDER have a feature that removes leading zeroes michael@0: out of SEC_ASN1_INTEGER if the caller sets siUnsignedInteger in the type michael@0: field of the target SECItem prior to calling the decoder. Otherwise, the michael@0: type field is ignored and untouched. For SECItem that are dynamically michael@0: allocated (from POINTER, SET OF, SEQUENCE OF) the decoder sets the type michael@0: field to siBuffer. */ michael@0: michael@0: extern SECStatus SEC_ASN1DecodeItem(PLArenaPool *pool, void *dest, michael@0: const SEC_ASN1Template *t, michael@0: const SECItem *src); michael@0: michael@0: extern SECStatus SEC_QuickDERDecodeItem(PLArenaPool* arena, void* dest, michael@0: const SEC_ASN1Template* templateEntry, michael@0: const SECItem* src); michael@0: michael@0: /* michael@0: ** Encoding. michael@0: */ michael@0: michael@0: extern SEC_ASN1EncoderContext *SEC_ASN1EncoderStart(const void *src, michael@0: const SEC_ASN1Template *t, michael@0: SEC_ASN1WriteProc fn, michael@0: void *output_arg); michael@0: michael@0: /* XXX char or unsigned char? */ michael@0: extern SECStatus SEC_ASN1EncoderUpdate(SEC_ASN1EncoderContext *cx, michael@0: const char *buf, michael@0: unsigned long len); michael@0: michael@0: extern void SEC_ASN1EncoderFinish(SEC_ASN1EncoderContext *cx); michael@0: michael@0: /* Higher level code detected an error, abort the rest of the processing */ michael@0: extern void SEC_ASN1EncoderAbort(SEC_ASN1EncoderContext *cx, int error); michael@0: michael@0: extern void SEC_ASN1EncoderSetNotifyProc(SEC_ASN1EncoderContext *cx, michael@0: SEC_ASN1NotifyProc fn, michael@0: void *arg); michael@0: michael@0: extern void SEC_ASN1EncoderClearNotifyProc(SEC_ASN1EncoderContext *cx); michael@0: michael@0: extern void SEC_ASN1EncoderSetStreaming(SEC_ASN1EncoderContext *cx); michael@0: michael@0: extern void SEC_ASN1EncoderClearStreaming(SEC_ASN1EncoderContext *cx); michael@0: michael@0: extern void sec_ASN1EncoderSetDER(SEC_ASN1EncoderContext *cx); michael@0: michael@0: extern void sec_ASN1EncoderClearDER(SEC_ASN1EncoderContext *cx); michael@0: michael@0: extern void SEC_ASN1EncoderSetTakeFromBuf(SEC_ASN1EncoderContext *cx); michael@0: michael@0: extern void SEC_ASN1EncoderClearTakeFromBuf(SEC_ASN1EncoderContext *cx); michael@0: michael@0: extern SECStatus SEC_ASN1Encode(const void *src, const SEC_ASN1Template *t, michael@0: SEC_ASN1WriteProc output_proc, michael@0: void *output_arg); michael@0: michael@0: /* michael@0: * If both pool and dest are NULL, the caller should free the returned SECItem michael@0: * with a SECITEM_FreeItem(..., PR_TRUE) call. If pool is NULL but dest is michael@0: * not NULL, the caller should free the data buffer pointed to by dest with a michael@0: * SECITEM_FreeItem(dest, PR_FALSE) or PORT_Free(dest->data) call. michael@0: */ michael@0: extern SECItem * SEC_ASN1EncodeItem(PLArenaPool *pool, SECItem *dest, michael@0: const void *src, const SEC_ASN1Template *t); michael@0: michael@0: extern SECItem * SEC_ASN1EncodeInteger(PLArenaPool *pool, michael@0: SECItem *dest, long value); michael@0: michael@0: extern SECItem * SEC_ASN1EncodeUnsignedInteger(PLArenaPool *pool, michael@0: SECItem *dest, michael@0: unsigned long value); michael@0: michael@0: extern SECStatus SEC_ASN1DecodeInteger(SECItem *src, michael@0: unsigned long *value); michael@0: michael@0: /* michael@0: ** Utilities. michael@0: */ michael@0: michael@0: /* michael@0: * We have a length that needs to be encoded; how many bytes will the michael@0: * encoding take? michael@0: */ michael@0: extern int SEC_ASN1LengthLength (unsigned long len); michael@0: michael@0: /* encode the length and return the number of bytes we encoded. Buffer michael@0: * must be pre allocated */ michael@0: extern int SEC_ASN1EncodeLength(unsigned char *buf,int value); michael@0: michael@0: /* michael@0: * Find the appropriate subtemplate for the given template. michael@0: * This may involve calling a "chooser" function, or it may just michael@0: * be right there. In either case, it is expected to *have* a michael@0: * subtemplate; this is asserted in debug builds (in non-debug michael@0: * builds, NULL will be returned). michael@0: * michael@0: * "thing" is a pointer to the structure being encoded/decoded michael@0: * "encoding", when true, means that we are in the process of encoding michael@0: * (as opposed to in the process of decoding) michael@0: */ michael@0: extern const SEC_ASN1Template * michael@0: SEC_ASN1GetSubtemplate (const SEC_ASN1Template *inTemplate, void *thing, michael@0: PRBool encoding); michael@0: michael@0: /* whether the template is for a primitive type or a choice of michael@0: * primitive types michael@0: */ michael@0: extern PRBool SEC_ASN1IsTemplateSimple(const SEC_ASN1Template *theTemplate); michael@0: michael@0: /************************************************************************/ michael@0: michael@0: /* michael@0: * Generic Templates michael@0: * One for each of the simple types, plus a special one for ANY, plus: michael@0: * - a pointer to each one of those michael@0: * - a set of each one of those michael@0: * - a sequence of each one of those michael@0: * michael@0: * Note that these are alphabetical (case insensitive); please add new michael@0: * ones in the appropriate place. michael@0: */ michael@0: michael@0: extern const SEC_ASN1Template SEC_AnyTemplate[]; michael@0: extern const SEC_ASN1Template SEC_BitStringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_BMPStringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_BooleanTemplate[]; michael@0: extern const SEC_ASN1Template SEC_EnumeratedTemplate[]; michael@0: extern const SEC_ASN1Template SEC_GeneralizedTimeTemplate[]; michael@0: extern const SEC_ASN1Template SEC_IA5StringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_IntegerTemplate[]; michael@0: extern const SEC_ASN1Template SEC_NullTemplate[]; michael@0: extern const SEC_ASN1Template SEC_ObjectIDTemplate[]; michael@0: extern const SEC_ASN1Template SEC_OctetStringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_PrintableStringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_T61StringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_UniversalStringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_UTCTimeTemplate[]; michael@0: extern const SEC_ASN1Template SEC_UTF8StringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_VisibleStringTemplate[]; michael@0: michael@0: extern const SEC_ASN1Template SEC_PointerToAnyTemplate[]; michael@0: extern const SEC_ASN1Template SEC_PointerToBitStringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_PointerToBMPStringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_PointerToBooleanTemplate[]; michael@0: extern const SEC_ASN1Template SEC_PointerToEnumeratedTemplate[]; michael@0: extern const SEC_ASN1Template SEC_PointerToGeneralizedTimeTemplate[]; michael@0: extern const SEC_ASN1Template SEC_PointerToIA5StringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_PointerToIntegerTemplate[]; michael@0: extern const SEC_ASN1Template SEC_PointerToNullTemplate[]; michael@0: extern const SEC_ASN1Template SEC_PointerToObjectIDTemplate[]; michael@0: extern const SEC_ASN1Template SEC_PointerToOctetStringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_PointerToPrintableStringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_PointerToT61StringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_PointerToUniversalStringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_PointerToUTCTimeTemplate[]; michael@0: extern const SEC_ASN1Template SEC_PointerToUTF8StringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_PointerToVisibleStringTemplate[]; michael@0: michael@0: extern const SEC_ASN1Template SEC_SequenceOfAnyTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SequenceOfBitStringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SequenceOfBMPStringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SequenceOfBooleanTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SequenceOfEnumeratedTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SequenceOfGeneralizedTimeTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SequenceOfIA5StringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SequenceOfIntegerTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SequenceOfNullTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SequenceOfObjectIDTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SequenceOfOctetStringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SequenceOfPrintableStringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SequenceOfT61StringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SequenceOfUniversalStringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SequenceOfUTCTimeTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SequenceOfUTF8StringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SequenceOfVisibleStringTemplate[]; michael@0: michael@0: extern const SEC_ASN1Template SEC_SetOfAnyTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SetOfBitStringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SetOfBMPStringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SetOfBooleanTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SetOfEnumeratedTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SetOfGeneralizedTimeTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SetOfIA5StringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SetOfIntegerTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SetOfNullTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SetOfObjectIDTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SetOfOctetStringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SetOfPrintableStringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SetOfT61StringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SetOfUniversalStringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SetOfUTCTimeTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SetOfUTF8StringTemplate[]; michael@0: extern const SEC_ASN1Template SEC_SetOfVisibleStringTemplate[]; michael@0: michael@0: /* michael@0: * Template for skipping a subitem; this only makes sense when decoding. michael@0: */ michael@0: extern const SEC_ASN1Template SEC_SkipTemplate[]; michael@0: michael@0: /* These functions simply return the address of the above-declared templates. michael@0: ** This is necessary for Windows DLLs. Sigh. michael@0: */ michael@0: SEC_ASN1_CHOOSER_DECLARE(SEC_AnyTemplate) michael@0: SEC_ASN1_CHOOSER_DECLARE(SEC_BMPStringTemplate) michael@0: SEC_ASN1_CHOOSER_DECLARE(SEC_BooleanTemplate) michael@0: SEC_ASN1_CHOOSER_DECLARE(SEC_BitStringTemplate) michael@0: SEC_ASN1_CHOOSER_DECLARE(SEC_GeneralizedTimeTemplate) michael@0: SEC_ASN1_CHOOSER_DECLARE(SEC_IA5StringTemplate) michael@0: SEC_ASN1_CHOOSER_DECLARE(SEC_IntegerTemplate) michael@0: SEC_ASN1_CHOOSER_DECLARE(SEC_NullTemplate) michael@0: SEC_ASN1_CHOOSER_DECLARE(SEC_ObjectIDTemplate) michael@0: SEC_ASN1_CHOOSER_DECLARE(SEC_OctetStringTemplate) michael@0: SEC_ASN1_CHOOSER_DECLARE(SEC_UTCTimeTemplate) michael@0: SEC_ASN1_CHOOSER_DECLARE(SEC_UTF8StringTemplate) michael@0: michael@0: SEC_ASN1_CHOOSER_DECLARE(SEC_PointerToAnyTemplate) michael@0: SEC_ASN1_CHOOSER_DECLARE(SEC_PointerToOctetStringTemplate) michael@0: michael@0: SEC_ASN1_CHOOSER_DECLARE(SEC_SetOfAnyTemplate) michael@0: michael@0: SEC_ASN1_CHOOSER_DECLARE(SEC_EnumeratedTemplate) michael@0: SEC_ASN1_CHOOSER_DECLARE(SEC_PointerToEnumeratedTemplate) michael@0: SEC_ASN1_CHOOSER_DECLARE(SEC_SequenceOfAnyTemplate) michael@0: SEC_ASN1_CHOOSER_DECLARE(SEC_SequenceOfObjectIDTemplate) michael@0: SEC_ASN1_CHOOSER_DECLARE(SEC_SkipTemplate) michael@0: SEC_ASN1_CHOOSER_DECLARE(SEC_UniversalStringTemplate) michael@0: SEC_ASN1_CHOOSER_DECLARE(SEC_PrintableStringTemplate) michael@0: SEC_ASN1_CHOOSER_DECLARE(SEC_T61StringTemplate) michael@0: SEC_ASN1_CHOOSER_DECLARE(SEC_PointerToGeneralizedTimeTemplate) michael@0: SEC_END_PROTOS michael@0: #endif /* _SECASN1_H_ */