view libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c @ 1499:2d450c1056e3

options: Complete the transition to numeric toggles (`#if') For the sake of review, this commit alters only the code; the affiliated comments within the source files also need to be updated, but doing so now would obscure the operational changes that have been made here. * All on/off options have been switched to the numeric `#if' variant; that is the only way to make this `default_options.h.in' thing work in a reasonable manner. * There is now some very minor compile-time checking of the user's choice of options. * NO_FAST_EXPTMOD doesn't seem to be used, so it has been removed. * ENABLE_USER_ALGO_LIST was supposed to be renamed DROPBEAR_USER_ALGO_LIST, and this commit completes that work. * DROPBEAR_FUZZ seems to be a relatively new, as-yet undocumented option, which was added by the following commit: commit 6e0b539e9ca0b5628c6c5a3d118ad6a2e79e8039 Author: Matt Johnston <[email protected]> Date: Tue May 23 22:29:21 2017 +0800 split out checkpubkey_line() separately It has now been added to `sysoptions.h' and defined as `0' by default. * The configuration option `DROPBEAR_PASSWORD_ENV' is no longer listed in `default_options.h.in'; it is no longer meant to be set by the user, and is instead left to be defined in `sysoptions.h' (where it was already being defined) as merely the name of the environment variable in question: DROPBEAR_PASSWORD To enable or disable use of that environment variable, the user must now toggle `DROPBEAR_USE_DROPBEAR_PASSWORD'. * The sFTP support is now toggled by setting `DROPBEAR_SFTPSERVER', and the path of the sFTP server program is set independently through the usual SFTPSERVER_PATH.
author Michael Witten <mfwitten@gmail.com>
date Thu, 20 Jul 2017 19:38:26 +0000
parents 6dba84798cd5
children
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.
 */
#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_BOOLEAN:
               if (der_decode_boolean(in, *inlen, data) == CRYPT_OK) {
                  if (der_length_boolean(&z) == CRYPT_OK) {
                      list[x].used = 1;
                      *inlen       = z;
                      return CRYPT_OK;
                  }
               }
               break;

           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_RAW_BIT_STRING:
               if (der_decode_raw_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;
                  list[x].used   = 1;
                  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_TELETEX_STRING:
               if (der_decode_teletex_string(in, *inlen, data, &size) == CRYPT_OK) {
                  if (der_length_teletex_string(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_UTF8_STRING:
               if (der_decode_utf8_string(in, *inlen, data, &size) == CRYPT_OK) {
                  if (der_length_utf8_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_GENERALIZEDTIME:
               z = *inlen;
               if (der_decode_generalizedtime(in, &z, data) == CRYPT_OK) {
                  list[x].used = 1;
                  *inlen       = z;
                  return CRYPT_OK;
               }
               break;

           case LTC_ASN1_SET:
           case LTC_ASN1_SETOF:
           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;

           case LTC_ASN1_CHOICE:
           case LTC_ASN1_CONSTRUCTED:
           case LTC_ASN1_CONTEXT_SPECIFIC:
           case LTC_ASN1_EOL:
               return CRYPT_INVALID_ARG;
       }
   }

   return CRYPT_INVALID_PACKET;
}

#endif

/* ref:         $Format:%D$ */
/* git commit:  $Format:%H$ */
/* commit time: $Format:%ai$ */