diff src/pk/asn1/der/sequence/der_length_sequence.c @ 209:39d5d58461d6 libtomcrypt-orig LTC_1.05

Import of libtomcrypt 1.05
author Matt Johnston <matt@ucc.asn.au>
date Wed, 06 Jul 2005 03:53:40 +0000
parents
children d5faf4814ddb
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/sequence/der_length_sequence.c	Wed Jul 06 03:53:40 2005 +0000
@@ -0,0 +1,144 @@
+/* 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"
+#include <stdarg.h>
+
+
+/**
+  @file der_length_sequence.c
+  ASN.1 DER, length a SEQUENCE, Tom St Denis
+*/
+
+#ifdef LTC_DER
+
+/**
+   Get the length of a DER sequence 
+   @param list   The sequences of items in the SEQUENCE
+   @param inlen  The number of items
+   @param outlen [out] The length required in octets to store it 
+   @return CRYPT_OK on success
+*/
+int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
+                        unsigned long *outlen) 
+{
+   int           err, type;
+   unsigned long size, x, y, z, i;
+   void          *data;
+
+   LTC_ARGCHK(list    != NULL);
+   LTC_ARGCHK(outlen  != NULL);
+
+   /* get size of output that will be required */
+   y = 0;
+   for (i = 0; i < inlen; i++) {
+       type = list[i].type;
+       size = list[i].size;
+       data = list[i].data;
+
+       if (type == LTC_ASN1_EOL) { 
+          break;
+       }
+
+       switch (type) {
+           case LTC_ASN1_INTEGER:
+               if ((err = der_length_integer(data, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+           case LTC_ASN1_SHORT_INTEGER:
+               if ((err = der_length_short_integer(*((unsigned long *)data), &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+           case LTC_ASN1_BIT_STRING:
+               if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+           case LTC_ASN1_OCTET_STRING:
+               if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+           case LTC_ASN1_NULL:
+               y += 2;
+               break;
+
+           case LTC_ASN1_OBJECT_IDENTIFIER:
+               if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+           case LTC_ASN1_IA5_STRING:
+               if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+           case LTC_ASN1_PRINTABLE_STRING:
+               if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+           case LTC_ASN1_SEQUENCE:
+               if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+          
+           default:
+               err = CRYPT_INVALID_ARG;
+               goto LBL_ERR;
+       }
+   }
+
+   /* calc header size */
+   z = y;
+   if (y < 128) {
+      y += 2;
+   } else if (y < 256) {
+      /* 0x30 0x81 LL */
+      y += 3;
+   } else if (y < 65536UL) {
+      /* 0x30 0x82 LL LL */
+      y += 4;
+   } else if (y < 16777216UL) {
+      /* 0x30 0x83 LL LL LL */
+      y += 5;
+   } else {
+      err = CRYPT_INVALID_ARG;
+      goto LBL_ERR;
+   }
+
+   /* store size */
+   *outlen = y;
+   err     = CRYPT_OK;
+
+LBL_ERR:
+   return err;
+}
+
+#endif