asn1_k_decode.c revision 159d09a20817016f09b3ea28d1bdada4a336bb91
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
*
* Copyright 1994 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
* require a specific license from the United States Government.
* It is the responsibility of any person or organization contemplating
* export to obtain such a license before exporting.
*
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
* distribute this software and its documentation for any purpose and
* without fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright notice and
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
* permission. Furthermore if you modify this software you must label
* your software as modified software and not distribute it in such a
* fashion that it might be confused with the original M.I.T. software.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
*/
#include "asn1_k_decode.h"
#include "asn1_decode.h"
#include "asn1_get.h"
#include "asn1_misc.h"
/* Declare useful decoder variables. */
#define setup() \
#define unused_var(x) if (0) { x = 0; x = x - x; }
/* This is used for prefetch of next tag in sequence. */
#define next_tag() \
/* Copy out to match previous functionality, until better integrated. */ \
}
/* Force check for EOC tag. */
#define get_eoc() \
{ \
return ASN1_MISSING_EOC; \
/* Copy out to match previous functionality, until better integrated. */ \
}
/* Fetch an expected APPLICATION class tag and verify. */
{ \
/* Copy out to match previous functionality, until better integrated. */ \
}
/**** normal fields ****/
/*
* get_field_body
*
* Get bare field. This also prefetches the next tag. The call to
* get_eoc() assumes that any values fetched by this macro are
* enclosed in a context-specific tag.
*/
next_tag()
/*
* get_field
*
* Get field having an expected context specific tag. This assumes
* that context-specific tags are monotonically increasing in its
* verification of tag numbers.
*/
return ASN1_BAD_ID; \
/*
* opt_field
*
* Get an optional field with an expected context specific tag.
* Assumes that OPTVAL will have the default value, thus failing to
* distinguish between absent optional values and present optional
* values that happen to have the value of OPTVAL.
*/
return ASN1_BAD_ID; \
}
/**** fields w/ length ****/
/* similar to get_field_body */
next_tag()
/* similar to get_field_body */
return ASN1_BAD_ID; \
/* similar to opt_field */
/*
* Deal with implicitly tagged fields
*/
return ASN1_BAD_ID; \
next_tag()
return ASN1_BAD_ID; \
next_tag(); \
/*
* begin_structure
*
* Declares some variables for decoding SEQUENCE types. This is meant
* to be called in an inner block that ends with a call to
* end_structure().
*/
#define begin_structure() \
int seqindef; \
int indef; \
next_tag()
/*
* This is used for structures which have no tagging.
* It is the same as begin_structure() except next_tag()
* is not called.
*/
#define begin_structure_no_tag() \
int seqindef; \
int indef; \
/* skip trailing garbage */
#define end_structure() \
/*
* begin_choice
*
* Declares some variables for decoding CHOICE types. This is meant
* to be called in an inner block that ends with a call to
* end_choice().
*/
#define begin_choice() \
int seqindef; \
int indef; \
taginfo t; \
construction = t.construction; \
/* skip trailing garbage */
#define end_choice() \
/*
* sequence_of
*
* Declares some variables for decoding SEQUENCE OF types. This is
* meant to be called in an inner block that ends with a call to
* end_sequence_of().
*/
#define sequence_of(buf) \
int indef; \
/*
* sequence_of_no_tagvars
*
* This is meant for use inside decoder functions that have an outer
* sequence structure and thus declares variables of different names
* than does sequence_of() to avoid shadowing.
*/
#define sequence_of_no_tagvars(buf) \
unsigned int eseqlen; \
int eseqindef; \
/*
* sequence_of_common
*
* Fetches the outer SEQUENCE OF length info into {length,seqofindef}
* and imbeds an inner buffer seqbuf. Unlike begin_structure(), it
* does not prefetch the next tag.
*/
#define sequence_of_common(buf) \
int size = 0; \
int seqofindef; \
/*
* end_sequence_of
*
* Attempts to fetch an EOC tag, if any, and to sync over trailing
* garbage, if any.
*/
#define end_sequence_of(buf) \
{ \
/* Copy out to match previous functionality, until better integrated. */ \
} \
/*
* end_sequence_of_no_tagvars
*
* Like end_sequence_of(), but uses the different (non-shadowing)
* variable names.
*/
#define end_sequence_of_no_tagvars(buf) \
{ \
/* Copy out to match previous functionality, until better integrated. */ \
} \
#define cleanup() \
return 0
/* scalars */
{
time_t t;
if (retval)
return retval;
*val = t;
return 0;
}
{\
long n;\
return 0;\
}
{\
unsigned long n;\
return 0;\
}
{
unsigned long n;
return 0;
}
{
unsigned long n;
*val = (krb5_msgtype) n;
return 0;
}
/* structures */
{
return asn1_decode_generalstring(buf,
}
{
setup();
{ begin_structure();
size++;
else
}
}
if (indef) {
get_eoc();
}
next_tag();
}
cleanup();
}
{
setup();
{ begin_structure();
}
cleanup();
}
{
setup();
{ begin_structure();
}
cleanup();
}
{
setup();
{ begin_structure();
}
cleanup();
}
{
asn1_octet unused, o;
taginfo t;
int i;
krb5_flags f=0;
unsigned int length;
t.tagnum != ASN1_BITSTRING)
return ASN1_BAD_ID;
/* Number of unused bits must be between 0 and 7. */
length--;
for(i = 0; i < length; i++) {
/* ignore bits past number 31 */
if (i < 4)
}
if (length <= 4) {
/* Mask out unused bits, but only if necessary. */
f &= ~(krb5_flags)0 << unused;
}
/* left-justify */
if (length < 4)
*val = f;
return 0;
}
{
setup();
{ begin_structure();
}
cleanup();
}
{
setup();
{ begin_structure();
/* Set to authtime if missing */
}
cleanup();
}
{
setup();
unsigned int applen;
apptag(1);
{ begin_structure();
}
if (!applen) {
taginfo t;
}
cleanup();
}
{
setup();
{ begin_structure();
}
cleanup();
}
{
setup();
{
/* If opt_field server is missing, memory reference to server is
lost and results in memory leak */
}
}
if(tagnum == 10){
else{
}
}
cleanup();
}
{
setup();
{ begin_structure();
if(tagnum == 5){
}
cleanup();
}
{
setup();
{ begin_structure();
}
cleanup();
}
{
setup();
{ begin_structure();
}
cleanup();
}
/* arrays */
size++;\
else\
\
{ sequence_of(buf);\
}\
}\
cleanup()
{
}
{
setup();
{ begin_structure();
}
cleanup();
}
{
}
{
}
{
}
{
setup();
{ begin_structure();
if(tagnum == 1){
if(tagnum == 8){
}
cleanup();
}
{
}
{
setup();
{ begin_structure();
}
cleanup();
}
{
}
{
setup();
{ begin_structure();
#ifdef KRB5_GENEROUS_LR_TYPE
/* If we are only a single byte wide and negative - fill in the
other bits */
#endif
}
cleanup();
}
{
{ sequence_of(buf);
size++;
else
}
}
cleanup();
}
{
}
{
/*
* Solaris Kerberos:
* Use a temporary char* (tmpp) in place of val->salt when calling
* get_lenfield(). val->salt cannot be cast to a char* as casting will not
* produce an lvalue. Use the new value pointed to by tmpp as the value for
* val->salt.
*/
char *tmpp;
setup();
{ begin_structure();
if (tagnum == 1) {
} else {
}
if ( tagnum ==2) {
krb5_octet *params ;
} else {
}
}
cleanup();
}
{
setup();
{ begin_structure();
if (tagnum == 1) {
} else {
}
if ( tagnum ==2) {
krb5_octet *params ;
} else {
}
}
cleanup();
}
{
setup();
{ begin_structure();
if (tagnum == 1) {
} else {
}
}
cleanup();
}
{
}
{
if (v1_3_behavior) {
} else {
}
}
{
setup();
{ begin_structure();
}
cleanup();
}
{
}
{
setup();
{ begin_structure();
}
cleanup();
}
{
setup();
if (tagnum != 0) return ASN1_MISSING_FIELD;
return ASN1_BAD_ID;
}
return ENOMEM;
next_tag();
}
cleanup();
}
{
setup();
{ begin_structure();
}
cleanup();
}
{
setup();
{ begin_structure();
/* alloc_field(val->sam_key,krb5_keyblock); */
}
cleanup();
}
{
setup();
{ begin_structure();
}
cleanup();
}
{
setup();
{ begin_structure();
}
cleanup();
}
else{\
}
{
setup();
{ begin_structure();
}
cleanup();
}
{
setup();
{ begin_structure();
}
cleanup();
}
{
setup();
{ begin_structure();
}
cleanup();
}
/* PKINIT */
asn1_error_code asn1_decode_external_principal_identifier(asn1buf *buf, krb5_external_principal_identifier *val)
{
setup();
{
}
cleanup();
}
asn1_error_code asn1_decode_sequence_of_external_principal_identifier(asn1buf *buf, krb5_external_principal_identifier ***val)
{
}
{
setup();
{
}
cleanup();
}
#if 0 /* XXX This needs to be tested!!! XXX */
{
setup();
{
if (t.tagnum == choice_trusted_cas_principalName) {
} else if (t.tagnum == choice_trusted_cas_caName) {
{
}
return ENOMEM;
next_tag();
} else if (t.tagnum == choice_trusted_cas_issuerAndSerial) {
{
}
return ENOMEM;
next_tag();
} else return ASN1_BAD_ID;
}
cleanup();
}
#else
{
setup();
{ begin_choice();
if (tagnum == choice_trusted_cas_principalName) {
} else if (tagnum == choice_trusted_cas_caName) {
} else if (tagnum == choice_trusted_cas_issuerAndSerial) {
} else return ASN1_BAD_ID;
end_choice();
}
cleanup();
}
#endif
{
}
{
setup();
{ begin_structure();
}
cleanup();
}
{
setup();
{ begin_structure();
}
cleanup();
}
{
setup();
{ begin_structure();
}
cleanup();
}
asn1_error_code asn1_decode_pk_authenticator_draft9(asn1buf *buf, krb5_pk_authenticator_draft9 *val)
{
setup();
{ begin_structure();
}
cleanup();
}
setup();
/*
* Forbid indefinite encoding because we don't read enough tag
* information from the trailing octets ("ANY DEFINED BY") to
* synchronize EOC tags, etc.
*/
if (seqindef) return ASN1_BAD_FORMAT;
/*
* Set up tag variables because we don't actually call anything
* that fetches tag info for us; it's all buried in the decoder
* primitives.
*/
taglen = 0;
indef = 0;
}
}
cleanup();
}
{
setup();
/* SubjectPublicKey encoded as a BIT STRING */
next_tag();
tagnum != ASN1_BITSTRING)
return ASN1_BAD_ID;
/* Number of unused bits must be between 0 and 7. */
/* What to do if unused is not zero? */
taglen--;
/*
* We didn't call any macro that does next_tag(); do so now to
* preload tag of any trailing encodings.
*/
next_tag();
}
cleanup();
}
asn1_error_code asn1_decode_sequence_of_algorithm_identifier(asn1buf *buf, krb5_algorithm_identifier ***val)
{
}
{
setup();
{ begin_structure();
next_tag();
}
cleanup();
}
{
setup();
{ begin_structure();
}
cleanup();
}
{
setup();
{ begin_structure();
}
cleanup();
}
{
setup();
{ begin_structure();
}
cleanup();
}
{
setup();
{ begin_structure();
/* can't call opt_field because it does decoder(&subbuf, &(val)); */
return ASN1_BAD_ID;
if (tagnum == 1) {
next_tag();
}
/* can't call opt_field because it does decoder(&subbuf, &(val)); */
if (tagnum == 2) {
next_tag();
}
}
cleanup();
}
{
setup();
{ begin_structure();
if (tagnum == 1) {
/* can't call opt_field because it does decoder(&subbuf, &(val)); */
return ASN1_BAD_ID;
if (tagnum == 1) {
next_tag();
}
}
}
cleanup();
}
{
setup();
{ begin_choice();
if (tagnum == choice_pa_pk_as_rep_dhInfo) {
} else if (tagnum == choice_pa_pk_as_rep_encKeyPack) {
} else {
}
end_choice();
}
cleanup();
}
{
setup();
{ begin_structure();
} else if (tagnum == choice_pa_pk_as_rep_draft9_encKeyPack) {
} else {
}
}
cleanup();
}
{
}
{
setup();
{ begin_structure();
}
cleanup();
}