Added SILC_ASN1_SHORT_INT.
authorPekka Riikonen <priikone@silcnet.org>
Sun, 1 Jan 2006 16:21:11 +0000 (16:21 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sun, 1 Jan 2006 16:21:11 +0000 (16:21 +0000)
CHANGES
TODO
lib/silcasn1/silcasn1.c
lib/silcasn1/silcasn1.h
lib/silcasn1/silcasn1_decode.c
lib/silcasn1/silcasn1_encode.c
lib/silcasn1/silcasn1_i.h
lib/silcasn1/tests/test_silcasn1.c
lib/silccrypt/rsa.c
lib/silccrypt/silcpk.c
lib/silccrypt/silcpkcs1.c

diff --git a/CHANGES b/CHANGES
index 432bd167f0eb0aa95a9224e8708c9e130a8c31e0..d92c5e2401b7bae4f666c98311116d7ec6671759 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,4 @@
-Sat Dec 30 22:54:21 EET 2005  Pekka Riikonen <priikone@silcnet.org>
+Fri Dec 30 22:54:21 EET 2005  Pekka Riikonen <priikone@silcnet.org>
 
        * New SILC PKCS API enabling support for other public keys
          and certificates, lib/silccrypt/silcpkcs.[ch], silcpk.[ch].
diff --git a/TODO b/TODO
index 3f5aa5cfb4644318d7e7d69f18df4efbefd7d7d4..b455481c91a058acc5dd0fe211f196e7b2116c8b 100644 (file)
--- a/TODO
+++ b/TODO
@@ -175,6 +175,11 @@ lib/silcutil/silctime.[ch] ****DONE****
 lib/silcmath
 ============
 
+ o Import TFM.  Talk to Tom to add the missing functions.  Use TFM in
+   client and client library, but TMA in server, due to the significantly
+   increased memory consumption with TFM, and the rare need for public
+   key operations in server.
+
  o The SILC MP API function must start returning indication of success
    and failure of the operation.
 
index 007f1990d98fe6baa1680772d5850ba1c11d6e72..33be523fd2df1dfe5a815ee45ec457a3a91cea60 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2003 - 2005 Pekka Riikonen
+  Copyright (C) 2003 - 2006 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -94,6 +94,8 @@ const char *silc_asn1_tag_name(SilcAsn1Tag tag)
     return "set";
   case SILC_ASN1_TAG_INTEGER:
     return "integer";
+  case SILC_ASN1_TAG_SHORT_INTEGER:
+    return "short integer";
   case SILC_ASN1_TAG_OID:
     return "oid";
   case SILC_ASN1_TAG_BOOLEAN:
index 26c03f38256cfd34091d34dbdb20949db5be13f0..51a7015c96fb33675a85a871657b3d789c8648a1 100644 (file)
@@ -698,6 +698,29 @@ SilcBool silc_asn1_decode(SilcAsn1 asn1, SilcBuffer src, ...);
 #define SILC_ASN1_INT(x) SILC_ASN1_U1(INTEGER, x)
 #define SILC_ASN1_INT_T(o, t, x) SILC_ASN1_T1(INTEGER, o, t, x)
 
+/****f* silcasn1/SilcASN1API/SILC_ASN1_SHORT_INT
+ *
+ * SYNOPSIS
+ *
+ *    Encoding:
+ *    SILC_ASN1_SHORT_INT(integer)
+ *    SILC_ASN1_SHORT_INT_T(opts, tag, &integer)
+ *
+ *    Decoding:
+ *    SILC_ASN1_SHORT_INT(&integer)
+ *    SILC_ASN1_SHORT_INT_T(opts, tag, &integer);
+ *
+ * DESCRIPTION
+ *
+ *    Macro used to encode or decode short integer (32 bits).  The
+ *    integer type is SilcUInt32.
+ *
+ *    The `opts' is SilcAsn1Options.  The `tag' is a tag number.
+ *
+ ***/
+#define SILC_ASN1_SHORT_INT(x) SILC_ASN1_U1(SHORT_INTEGER, x)
+#define SILC_ASN1_SHORT_INT_T(o, t, x) SILC_ASN1_T1(SHORT_INTEGER, o, t, x)
+
 /****f* silcasn1/SilcASN1API/SILC_ASN1_ENUM
  *
  * SYNOPSIS
index 8fdfef24720343da660036fcb69806fb2d3f6e01..5fcfb4c7ec40e1e104969d81c31d8b8c241198b8 100644 (file)
@@ -310,6 +310,10 @@ silc_asn1_decoder(SilcAsn1 asn1, SilcStack stack1, SilcAsn1Tag type,
       }
     }
 
+    /* Short integer is actually big integer, so handle it correctly */
+    if (type == SILC_ASN1_TAG_SHORT_INTEGER && type == tag)
+      tag = SILC_ASN1_TAG_INTEGER;
+
     /* Now decode a BER encoded block from the source buffer.  It must be
        exactly the same user is expecting. */
     ret = silc_ber_decode(src, &rclass, &renc, (SilcUInt32 *)&rtag, &rdata,
@@ -483,6 +487,28 @@ silc_asn1_decoder(SilcAsn1 asn1, SilcStack stack1, SilcAsn1Tag type,
          break;
        }
 
+      case SILC_ASN1_TAG_SHORT_INTEGER:
+       {
+         /* Short Integer */
+         SilcMPInt z;
+         SILC_ASN1_VAD(asn1, opts, SilcUInt32, intval);
+
+         if (rdata_len < 1) {
+           SILC_LOG_DEBUG(("Malformed integer value"));
+           SILC_ASN1_VA_FREE(opts, intval);
+           ret = FALSE;
+           goto fail;
+         }
+
+         silc_stack_push(asn1->stack1, NULL);
+         silc_mp_sinit(asn1->stack1, &z);
+         silc_mp_bin2mp((unsigned char *)rdata, rdata_len, &z);
+         *(*intval) = silc_mp_get_ui(&z);
+         silc_mp_uninit(&z);
+         silc_stack_pop(asn1->stack1);
+         break;
+       }
+
       case SILC_ASN1_TAG_OID:
        {
          /* Object identifier */
@@ -493,6 +519,7 @@ silc_asn1_decoder(SilcAsn1 asn1, SilcStack stack1, SilcAsn1Tag type,
 
          if (rdata_len < 1) {
            SILC_LOG_DEBUG(("Malformed object identifier value"));
+           SILC_ASN1_VA_FREE(opts, oidstr);
            ret = FALSE;
            goto fail;
          }
@@ -553,6 +580,7 @@ silc_asn1_decoder(SilcAsn1 asn1, SilcStack stack1, SilcAsn1Tag type,
 
          if (rdata_len < 2) {
            SILC_LOG_DEBUG(("Malformed bit string value"));
+           SILC_ASN1_VA_FREE(opts, d);
            ret = FALSE;
            goto fail;
          }
@@ -579,6 +607,7 @@ silc_asn1_decoder(SilcAsn1 asn1, SilcStack stack1, SilcAsn1Tag type,
 
          if (rdata_len < 1) {
            SILC_LOG_DEBUG(("Malformed UTC time value"));
+           SILC_ASN1_VA_FREE(opts, t);
            ret = FALSE;
            goto fail;
          }
@@ -600,6 +629,7 @@ silc_asn1_decoder(SilcAsn1 asn1, SilcStack stack1, SilcAsn1Tag type,
 
          if (rdata_len < 1) {
            SILC_LOG_DEBUG(("Malformed generalized time value"));
+           SILC_ASN1_VA_FREE(opts, t);
            ret = FALSE;
            goto fail;
          }
@@ -607,6 +637,7 @@ silc_asn1_decoder(SilcAsn1 asn1, SilcStack stack1, SilcAsn1Tag type,
          /* Parse the time string */
          if (!silc_time_generalized(rdata, *t)) {
            SILC_LOG_DEBUG(("Malformed generalized time value"));
+           SILC_ASN1_VA_FREE(opts, t);
            ret = FALSE;
            goto fail;
          }
@@ -621,6 +652,7 @@ silc_asn1_decoder(SilcAsn1 asn1, SilcStack stack1, SilcAsn1Tag type,
 
          if (!silc_utf8_valid(rdata, rdata_len)) {
            SILC_LOG_DEBUG(("Malformed UTF-8 string value"));
+           SILC_ASN1_VA_FREE(opts, s);
            ret = FALSE;
            goto fail;
          }
index fb24c0648687beba13ed17346714c0c868f87a1d..d4b7077a25407e439843f8919ec54df48cfb49e1 100644 (file)
@@ -184,10 +184,7 @@ silc_asn1_encoder(SilcAsn1 asn1, SilcStack stack1, SilcStack stack2,
            SILC_LOG_DEBUG(("Error decoding underlaying node for ANY"));
            goto fail;
          }
-         if (enc != SILC_BER_ENC_CONSTRUCTED) {
-           SILC_LOG_DEBUG(("ANY was not constructed type"));
-           goto fail;
-         }
+         assert(enc == SILC_BER_ENC_CONSTRUCTED);
 
          /* Now encode with implicit tagging */
          len = silc_ber_encoded_len(tag, d_len, FALSE);
@@ -295,6 +292,45 @@ silc_asn1_encoder(SilcAsn1 asn1, SilcStack stack1, SilcStack stack2,
        break;
       }
 
+    case SILC_ASN1_TAG_SHORT_INTEGER:
+      {
+       /* Short Integer */
+       SilcUInt32 sint = va_arg(asn1->ap, SilcUInt32);
+       SilcMPInt z;
+
+       if (tag == SILC_ASN1_TAG_SHORT_INTEGER)
+         tag = SILC_ASN1_TAG_INTEGER;
+
+       memset(&buf, 0, sizeof(buf));
+
+       silc_stack_push(stack2, &frame);
+       silc_mp_sinit(stack2, &z);
+       silc_mp_set_ui(&z, sint);
+
+       len = silc_mp_sizeinbase(&z, 2);
+       if (!(len & 7))
+         len = ((len + 7) / 8) + 1;
+       else
+         len = (len + 7) / 8;
+       silc_buffer_srealloc_size(stack2, &buf,
+                                 silc_buffer_truelen(&buf) + len);
+       buf.data[0] = 0x00;
+       silc_mp_mp2bin_noalloc(&z, buf.data, silc_buffer_len(&buf));
+       silc_mp_uninit(&z);
+
+       /* Encode the integer */
+       len = silc_ber_encoded_len(tag, len, indef);
+       dest = silc_buffer_srealloc_size(stack1, dest,
+                                        silc_buffer_truelen(dest) + len);
+       ret = silc_ber_encode(dest, ber_class, SILC_BER_ENC_PRIMITIVE,
+                             tag, buf.data, silc_buffer_len(&buf), FALSE);
+       silc_stack_pop(stack2);
+       if (!ret)
+         goto fail;
+       break;
+      }
+      break;
+
     case SILC_ASN1_TAG_OID:
       {
        /* Object identifier */
index b602010548b5eb11bf37ce19fec8724f3700a395..122036755cd221868b10ea791ff237c5fe6a9f5d 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2003 - 2005 Pekka Riikonen
+  Copyright (C) 2003 - 2006 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -42,6 +42,7 @@ struct SilcAsn1Object {
 #define SILC_ASN1_TAG_CHOICE        0x7003  /* SILC_ASN1_CHOICE given */
 #define SILC_ASN1_TAG_SEQUENCE_OF   0x7004  /* SILC_ASN1_SEQUENCE_OF given */
 #define SILC_ASN1_TAG_ANY_PRIMITIVE 0x7005  /* Pre-encoded primitive data */
+#define SILC_ASN1_TAG_SHORT_INTEGER 0x7006  /* Short integer */
 
 /* Helper macros for adding the arguments to encoder and decoder. */
 
index 1400a2692627b9df669de167d915a3a274fc003f..2f2ec76caefe2b9c08b7612e8238170ce1eb6661 100644 (file)
@@ -51,7 +51,7 @@ int main(int argc, char **argv)
   SilcBool val = TRUE;
   int i;
   unsigned char *str;
-  SilcUInt32 str_len;
+  SilcUInt32 str_len, tmpint;
   char tmp[32];
   SilcRng rng;
   SilcMPInt mpint, mpint2;
@@ -710,6 +710,39 @@ int main(int argc, char **argv)
   printf("\n");
 
 
+  memset(&node, 0, sizeof(node));
+  SILC_LOG_DEBUG(("Encoding ASN.1 tree 12 (SHORT INTEGER)"));
+  str_len = 198761;
+  tmpint = 0;
+  SILC_LOG_DEBUG(("Short integer: %d", str_len));
+  SILC_LOG_DEBUG(("Short integer: %d", tmpint));
+  success =
+    silc_asn1_encode(asn1, &node,
+                    SILC_ASN1_SHORT_INT(str_len),
+                    SILC_ASN1_SHORT_INT_T(SILC_ASN1_IMPLICIT, 100, tmpint),
+                    SILC_ASN1_END);
+  if (!success) {
+    SILC_LOG_DEBUG(("Encoding failed"));
+    goto out;
+  }
+  SILC_LOG_DEBUG(("Encoding success"));
+  SILC_LOG_HEXDUMP(("ASN.1 tree"), node.data, silc_buffer_len(&node));
+  SILC_LOG_DEBUG(("Decoding ASN.1 tree 12 (SHORT INTEGER)"));
+  success =
+    silc_asn1_decode(asn1, &node,
+                    SILC_ASN1_SHORT_INT(&str_len),
+                    SILC_ASN1_SHORT_INT_T(SILC_ASN1_IMPLICIT, 100, &tmpint),
+                    SILC_ASN1_END);
+  if (!success) {
+    SILC_LOG_DEBUG(("Decoding failed"));
+    goto out;
+  }
+  SILC_LOG_DEBUG(("Short integer: %d", str_len));
+  SILC_LOG_DEBUG(("Short integer: %d", tmpint));
+  SILC_LOG_DEBUG(("Decoding success"));
+  printf("\n");
+
+
 #endif
   silc_asn1_free(asn1);
 
index b09693a591976c56e8d5599833415cc1ea785bc0..e58bca153c741c8c02b0d9d01b4f37de32c878c6 100644 (file)
 
      Fixed double free in public key setting.  Use a bit larger e as
      starting point in key generation.
-
-   o Fri Dec 30 13:39:51 EET 2005 Pekka
-
-     Support PKCS #1 format public and private keys.  Support for new
-     PKCS API.
 */
 
 #include "silc.h"
index 0de35d6a57f7cb78425a6c5781bbc5ef1db259e6..d9b81cbad215b45f4669bfe33c84aaee1fff7a85 100644 (file)
@@ -971,7 +971,6 @@ SilcBool silc_pkcs_silc_import_private_key(unsigned char *key,
     /* Parse the RSA SILC private key */
     SilcBufferStruct k;
     SilcMPInt n, e, d, dp, dq, qp, p, q;
-    SilcMPInt version;
     unsigned char *tmp;
     SilcUInt32 len, ver;
 
@@ -1147,12 +1146,10 @@ SilcBool silc_pkcs_silc_import_private_key(unsigned char *key,
     }
 
     /* Encode to PKCS #1 format */
-    silc_mp_init(&version);
-    silc_mp_set_ui(&version, 0);
     memset(&alg_key, 0, sizeof(alg_key));
     if (!silc_asn1_encode(asn1, &alg_key,
                          SILC_ASN1_SEQUENCE,
-                           SILC_ASN1_INT(&version),
+                           SILC_ASN1_SHORT_INT(0),
                            SILC_ASN1_INT(&n),
                            SILC_ASN1_INT(&e),
                            SILC_ASN1_INT(&d),
@@ -1164,7 +1161,6 @@ SilcBool silc_pkcs_silc_import_private_key(unsigned char *key,
                          SILC_ASN1_END, SILC_ASN1_END))
       goto err;
 
-    silc_mp_uninit(&version);
     silc_mp_uninit(&n);
     silc_mp_uninit(&e);
     silc_mp_uninit(&e);
index 5820861d9fd36774b421dbf704d87b9728162588..88355e76349da013288da55aa1f0bc3298313562 100644 (file)
@@ -354,6 +354,7 @@ SilcBool silc_pkcs1_import_private_key(unsigned char *key,
   SilcAsn1 asn1;
   SilcBufferStruct alg_key;
   RsaPrivateKey *privkey;
+  SilcUInt32 ver;
 
   if (!ret_private_key)
     return FALSE;
@@ -372,7 +373,7 @@ SilcBool silc_pkcs1_import_private_key(unsigned char *key,
   if (!silc_asn1_decode(asn1, &alg_key,
                        SILC_ASN1_OPTS(SILC_ASN1_ALLOC),
                        SILC_ASN1_SEQUENCE,
-                         SILC_ASN1_INT(NULL),
+                         SILC_ASN1_SHORT_INT(&ver),
                          SILC_ASN1_INT(&privkey->n),
                          SILC_ASN1_INT(&privkey->e),
                          SILC_ASN1_INT(&privkey->d),
@@ -384,6 +385,9 @@ SilcBool silc_pkcs1_import_private_key(unsigned char *key,
                        SILC_ASN1_END, SILC_ASN1_END))
     goto err;
 
+  if (ver != 0)
+    goto err;
+
   /* Set key length */
   privkey->bits = silc_mp_sizeinbase(&privkey->n, 2);
 
@@ -404,7 +408,6 @@ unsigned char *silc_pkcs1_export_private_key(void *private_key,
   RsaPrivateKey *key = private_key;
   SilcAsn1 asn1;
   SilcBufferStruct alg_key;
-  SilcMPInt version;
   unsigned char *ret;
 
   asn1 = silc_asn1_alloc();
@@ -412,13 +415,11 @@ unsigned char *silc_pkcs1_export_private_key(void *private_key,
     return FALSE;
 
   /* Encode to PKCS #1 private key */
-  silc_mp_init(&version);
-  silc_mp_set_ui(&version, 0);
   memset(&alg_key, 0, sizeof(alg_key));
   if (!silc_asn1_encode(asn1, &alg_key,
                        SILC_ASN1_OPTS(SILC_ASN1_ALLOC),
                        SILC_ASN1_SEQUENCE,
-                         SILC_ASN1_INT(&version),
+                         SILC_ASN1_SHORT_INT(0),
                          SILC_ASN1_INT(&key->n),
                          SILC_ASN1_INT(&key->e),
                          SILC_ASN1_INT(&key->d),
@@ -429,7 +430,6 @@ unsigned char *silc_pkcs1_export_private_key(void *private_key,
                          SILC_ASN1_INT(&key->qP),
                        SILC_ASN1_END, SILC_ASN1_END))
     goto err;
-  silc_mp_uninit(&version);
 
   ret = silc_buffer_steal(&alg_key, ret_len);
   silc_asn1_free(asn1);