Mercurial > dropbear
view libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c @ 307:24b19535264b ucc-axis-hack
progress for serial logins
author | matt-ucc@ucc.asn.au |
---|---|
date | Sat, 25 Mar 2006 17:31:52 +0000 |
parents | 1b9e69c058d2 |
children | 0cbe8f6dbf9e |
line wrap: on
line source
/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, [email protected], http://libtomcrypt.org */ #include "tomcrypt.h" /** @file der_decode_choice.c ASN.1 DER, decode a CHOICE, Tom St Denis */ #ifdef LTC_DER /** Decode a CHOICE @param in The DER encoded input @param inlen [in/out] The size of the input and resulting size of read type @param list The list of items to decode @param outlen The number of items in the list @return CRYPT_OK on success */ int der_decode_choice(const unsigned char *in, unsigned long *inlen, ltc_asn1_list *list, unsigned long outlen) { unsigned long size, x, z; void *data; LTC_ARGCHK(in != NULL); LTC_ARGCHK(inlen != NULL); LTC_ARGCHK(list != NULL); /* get blk size */ if (*inlen < 2) { return CRYPT_INVALID_PACKET; } /* set all of the "used" flags to zero */ for (x = 0; x < outlen; x++) { list[x].used = 0; } /* now scan until we have a winner */ for (x = 0; x < outlen; x++) { size = list[x].size; data = list[x].data; switch (list[x].type) { case LTC_ASN1_INTEGER: if (der_decode_integer(in, *inlen, data) == CRYPT_OK) { if (der_length_integer(data, &z) == CRYPT_OK) { list[x].used = 1; *inlen = z; return CRYPT_OK; } } break; case LTC_ASN1_SHORT_INTEGER: if (der_decode_short_integer(in, *inlen, data) == CRYPT_OK) { if (der_length_short_integer(size, &z) == CRYPT_OK) { list[x].used = 1; *inlen = z; return CRYPT_OK; } } break; case LTC_ASN1_BIT_STRING: if (der_decode_bit_string(in, *inlen, data, &size) == CRYPT_OK) { if (der_length_bit_string(size, &z) == CRYPT_OK) { list[x].used = 1; list[x].size = size; *inlen = z; return CRYPT_OK; } } break; case LTC_ASN1_OCTET_STRING: if (der_decode_octet_string(in, *inlen, data, &size) == CRYPT_OK) { if (der_length_octet_string(size, &z) == CRYPT_OK) { list[x].used = 1; list[x].size = size; *inlen = z; return CRYPT_OK; } } break; case LTC_ASN1_NULL: if (*inlen == 2 && in[x] == 0x05 && in[x+1] == 0x00) { *inlen = 2; return CRYPT_OK; } break; case LTC_ASN1_OBJECT_IDENTIFIER: if (der_decode_object_identifier(in, *inlen, data, &size) == CRYPT_OK) { if (der_length_object_identifier(data, size, &z) == CRYPT_OK) { list[x].used = 1; list[x].size = size; *inlen = z; return CRYPT_OK; } } break; case LTC_ASN1_IA5_STRING: if (der_decode_ia5_string(in, *inlen, data, &size) == CRYPT_OK) { if (der_length_ia5_string(data, size, &z) == CRYPT_OK) { list[x].used = 1; list[x].size = size; *inlen = z; return CRYPT_OK; } } break; case LTC_ASN1_PRINTABLE_STRING: if (der_decode_printable_string(in, *inlen, data, &size) == CRYPT_OK) { if (der_length_printable_string(data, size, &z) == CRYPT_OK) { list[x].used = 1; list[x].size = size; *inlen = z; return CRYPT_OK; } } break; case LTC_ASN1_UTCTIME: z = *inlen; if (der_decode_utctime(in, &z, data) == CRYPT_OK) { list[x].used = 1; *inlen = z; return CRYPT_OK; } break; case LTC_ASN1_SEQUENCE: if (der_decode_sequence(in, *inlen, data, size) == CRYPT_OK) { if (der_length_sequence(data, size, &z) == CRYPT_OK) { list[x].used = 1; *inlen = z; return CRYPT_OK; } } break; default: return CRYPT_INVALID_ARG; } } return CRYPT_INVALID_PACKET; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c,v $ */ /* $Revision: 1.4 $ */ /* $Date: 2005/06/19 11:25:01 $ */