- some improvements to new asn1 stuff
authorMartin Willi <martin@strongswan.org>
Wed, 12 Apr 2006 08:38:10 +0000 (08:38 -0000)
committerMartin Willi <martin@strongswan.org>
Wed, 12 Apr 2006 08:38:10 +0000 (08:38 -0000)
- to be continued

Source/Makefile
Source/charon.kdevelop
Source/doc/Todo-list.txt
Source/lib/asn1-pluto/asn1-pluto.c
Source/lib/asn1-pluto/asn1-pluto.h
Source/lib/asn1-pluto/ttodata.c
Source/lib/crypto/rsa/rsa_private_key.c
Source/lib/crypto/rsa/rsa_public_key.c

index ceb9876..27a0ea3 100644 (file)
@@ -29,7 +29,7 @@ MAIN_DIR= ./
 
 LDFLAGS= -ldl -lgmp -lpthread -rdynamic
 
-CFLAGS= -Icharon -Ilib -Istroke -Wall -g -fPIC -DLEAK_DETECTIVE 
+CFLAGS= -Icharon -Ilib -Istroke -Wall -g -fPIC #-DLEAK_DETECTIVE 
 
 # objects is extended by each included Makefile
 CHARON_OBJS=
index 4ab9354..b3156ad 100644 (file)
@@ -13,6 +13,9 @@
       <mainprogram>Source</mainprogram>
       <directoryradio>executable</directoryradio>
     </run>
+    <general>
+      <activedir></activedir>
+    </general>
   </kdevcustomproject>
   <kdevdebugger>
     <general>
index 0942def..97bc16b 100644 (file)
@@ -1,7 +1,7 @@
- TODO-List for charon
+ Todo-List for charon
 ======================
 
-+ = done, - = todo, ordered by priority
++ = done, / = partial, - = todo, ordered by priority
 
 + private key loading: der, without passphrase
 + load all private keys from ipsec.d/private/ in stroke.c
     + utils (plus host)
     + logger_manager instance in lib
     + leak detective usable for charon and pluto and anything else
-    - doxygen fixes (multiple doxyfiles?)
-  - integrate asn1 parser/oid (asn1/oid)
-  - integrate PEM loading (pem)
-  - ... (more to come)
+    - doxygen split (charon/lib)
+  + integrate asn1 parser/oid (asn1/oid)
+  + integrate basic PEM loading
+  - 
+  - implement 3DES to load encrypted pem files
+  - port x509 stuff
+  - 
 
 - ipsec.secrets parsing
 
@@ -38,7 +41,6 @@
 - certificate exchange
 
 - trapping
-
 - delete notify, when to send?
 - notifys on connection setup failure
 - create child sa message
index 46764e1..01deb5c 100644 (file)
@@ -572,3 +572,168 @@ bool is_asn1(chunk_t blob)
        }
        return TRUE;
 }
+
+/*
+ * codes ASN.1 lengths up to a size of 16'777'215 bytes
+ */
+void code_asn1_length(size_t length, chunk_t *code)
+{
+       if (length < 128)
+       {
+               code->ptr[0] = length;
+               code->len = 1;
+       }
+       else if (length < 256)
+       {
+               code->ptr[0] = 0x81;
+               code->ptr[1] = (u_char) length;
+               code->len = 2;
+       }
+       else if (length < 65536)
+       {
+               code->ptr[0] = 0x82;
+               code->ptr[1] = length >> 8;
+               code->ptr[2] = length & 0x00ff;
+               code->len = 3;
+       }
+       else
+       {
+               code->ptr[0] = 0x83;
+               code->ptr[1] = length >> 16;
+               code->ptr[2] = (length >> 8) & 0x00ff;
+               code->ptr[3] = length & 0x0000ff;
+               code->len = 4;
+       }
+}
+
+/*
+ * build an empty asn.1 object with tag and length fields already filled in
+ */
+u_char* build_asn1_object(chunk_t *object, asn1_t type, size_t datalen)
+{
+       u_char length_buf[4];
+       chunk_t length = { length_buf, 0 };
+       u_char *pos;
+       
+       /* code the asn.1 length field */
+       code_asn1_length(datalen, &length);
+       
+       /* allocate memory for the asn.1 TLV object */
+       object->len = 1 + length.len + datalen;
+       object->ptr = malloc(object->len);
+       
+       /* set position pointer at the start of the object */
+       pos = object->ptr;
+       
+       /* copy the asn.1 tag field and advance the pointer */
+       *pos++ = type;
+       
+       /* copy the asn.1 length field and advance the pointer */
+       memcpy(pos, length.ptr, length.len); 
+       pos += length.len;
+       
+       return pos;
+}
+
+/*
+ * build a simple ASN.1 object
+ */
+chunk_t asn1_simple_object(asn1_t tag, chunk_t content)
+{
+       chunk_t object;
+       
+       u_char *pos = build_asn1_object(&object, tag, content.len);
+       memcpy(pos, content.ptr, content.len); 
+       pos += content.len;
+       
+       return object;
+}
+
+/* Build an ASN.1 object from a variable number of individual chunks.
+ * Depending on the mode, chunks either are moved ('m') or copied ('c').
+ */
+chunk_t asn1_wrap(asn1_t type, const char *mode, ...)
+{
+       chunk_t construct;
+       va_list chunks;
+       u_char *pos;
+       int i;
+       int count = strlen(mode);
+       
+       /* sum up lengths of individual chunks */ 
+       va_start(chunks, mode);
+       construct.len = 0;
+       for (i = 0; i < count; i++)
+       {
+               chunk_t ch = va_arg(chunks, chunk_t);
+               construct.len += ch.len;
+       }
+       va_end(chunks);
+       
+       /* allocate needed memory for construct */
+       pos = build_asn1_object(&construct, type, construct.len);
+       
+       /* copy or move the chunks */
+       va_start(chunks, mode);
+       for (i = 0; i < count; i++)
+       {
+               chunk_t ch = va_arg(chunks, chunk_t);
+               
+               switch (*mode++)
+               {
+                       case 'm':
+                               memcpy(pos, ch.ptr, ch.len); 
+                               pos += ch.len;
+                               free(ch.ptr);
+                               break;
+                       case 'c':
+                       default:
+                               memcpy(pos, ch.ptr, ch.len); 
+                               pos += ch.len;
+               }
+       }
+       va_end(chunks);
+       
+       return construct;
+}
+
+/*
+ * convert a MP integer into a DER coded ASN.1 object
+ */
+chunk_t asn1_integer_from_mpz(const mpz_t value)
+{
+       size_t bits = mpz_sizeinbase(value, 2);  /* size in bits */
+       chunk_t n;
+       n.len = 1 + bits / 8;  /* size in bytes */      
+       n.ptr = mpz_export(NULL, NULL, 1, n.len, 1, 0, value);
+       
+       return asn1_wrap(ASN1_INTEGER, "m", n);
+}
+
+/*
+ *  convert a date into ASN.1 UTCTIME or GENERALIZEDTIME format
+ */
+chunk_t timetoasn1(const time_t *time, asn1_t type)
+{
+       int offset;
+       const char *format;
+       char buf[TIMETOA_BUF];
+       chunk_t formatted_time;
+       struct tm *t = gmtime(time);
+       
+       if (type == ASN1_GENERALIZEDTIME)
+       {
+               format = "%04d%02d%02d%02d%02d%02dZ";
+               offset = 1900;
+       }
+       else /* ASN1_UTCTIME */
+       {
+               format = "%02d%02d%02d%02d%02d%02dZ";
+               offset = (t->tm_year < 100)? 0 : -100;
+       }
+       sprintf(buf, format, t->tm_year + offset, t->tm_mon + 1, t->tm_mday
+                       , t->tm_hour, t->tm_min, t->tm_sec);
+       formatted_time.ptr = buf;
+       formatted_time.len = strlen(buf);
+       return asn1_simple_object(type, formatted_time);
+}
index c7cc29e..3edaa32 100644 (file)
@@ -103,7 +103,6 @@ typedef struct {
 } asn1_ctx_t;
 
 /* some common prefabricated ASN.1 constants */
-
 extern const chunk_t ASN1_INTEGER_0;
 extern const chunk_t ASN1_INTEGER_1;
 extern const chunk_t ASN1_INTEGER_2;
@@ -115,6 +114,8 @@ extern const chunk_t ASN1_rsaEncryption_id;
 extern const chunk_t ASN1_md5WithRSA_id;
 extern const chunk_t ASN1_sha1WithRSA_id;
 
+#define TIMETOA_BUF 30
+
 extern chunk_t asn1_algorithmIdentifier(int oid);
 extern int known_oid(chunk_t object);
 extern u_int asn1_length(chunk_t *blob);
@@ -126,4 +127,11 @@ extern bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level,
 extern int parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters);
 extern bool is_asn1(chunk_t blob);
 
+extern void code_asn1_length(size_t length, chunk_t *code);
+extern u_char* build_asn1_object(chunk_t *object, asn1_t type, size_t datalen);
+extern chunk_t asn1_integer_from_mpz(const mpz_t value);
+extern chunk_t asn1_simple_object(asn1_t tag, chunk_t content);
+extern chunk_t asn1_wrap(asn1_t type, const char *mode, ...);
+extern chunk_t timetoasn1(const time_t *time, asn1_t type);
+
 #endif /* _ASN1_H */
index 3ef5acd..5e81499 100644 (file)
@@ -372,352 +372,3 @@ size_t errlen;
        strcat(errp, suf);
        return (const char *)errp;
 }
-
-
-
-#ifdef TTODATA_MAIN
-
-#include <stdio.h>
-
-struct artab;
-static void check(struct artab *r, char *buf, size_t n, err_t oops, int *status);
-static void regress(char *pgm);
-static void hexout(const char *s, size_t len, FILE *f);
-
-/*
- - main - convert first argument to hex, or run regression
- */
-int
-main(int argc, char *argv[])
-{
-       char buf[1024];
-       char buf2[1024];
-       char err[512];
-       size_t n;
-       size_t i;
-       char *p = buf;
-       char *p2 = buf2;
-       char *pgm = argv[0];
-       const char *oops;
-
-       if (argc < 2) {
-               fprintf(stderr, "Usage: %s {0x<hex>|0s<base64>|-r}\n", pgm);
-               exit(2);
-       }
-
-       if (strcmp(argv[1], "-r") == 0) {
-               regress(pgm);   /* should not return */
-               fprintf(stderr, "%s: regress() returned?!?\n", pgm);
-               exit(1);
-       }
-
-       oops = ttodatav(argv[1], 0, 0, buf, sizeof(buf), &n,
-                       err, sizeof(err), TTODATAV_IGNORESPACE);
-       if (oops != NULL) {
-               fprintf(stderr, "%s: ttodata error `%s' in `%s'\n", pgm,
-                                                               oops, argv[1]);
-               exit(1);
-       }
-
-       if (n > sizeof(buf)) {
-               p = (char *)malloc((size_t)n);
-               if (p == NULL) {
-                       fprintf(stderr,
-                               "%s: unable to malloc %d bytes for result\n",
-                               pgm, n);
-                       exit(1);
-               }
-               oops = ttodata(argv[1], 0, 0, p, n, &n);
-               if (oops != NULL) {
-                       fprintf(stderr, "%s: error `%s' in ttodata retry?!?\n",
-                                                               pgm, oops);
-                       exit(1);
-               }
-       }
-
-       hexout(p, n, stdout);
-       printf("\n");
-
-       i = datatot(buf, n, 'h', buf2, sizeof(buf2));
-       if (i == 0) {
-               fprintf(stderr, "%s: datatot reports error in `%s'\n", pgm,
-                                                               argv[1]);
-               exit(1);
-       }
-
-       if (i > sizeof(buf2)) {
-               p2 = (char *)malloc((size_t)i);
-               if (p == NULL) {
-                       fprintf(stderr,
-                               "%s: unable to malloc %d bytes for result\n",
-                               pgm, i);
-                       exit(1);
-               }
-               i = datatot(buf, n, 'h', p2, i);
-               if (i == 0) {
-                       fprintf(stderr, "%s: error in datatoa retry?!?\n", pgm);
-                       exit(1);
-               }
-       }
-
-       printf("%s\n", p2);
-
-       exit(0);
-}
-
-/*
- - hexout - output an arbitrary-length string in hex
- */
-static void
-hexout(s, len, f)
-const char *s;
-size_t len;
-FILE *f;
-{
-       size_t i;
-
-       fprintf(f, "0x");
-       for (i = 0; i < len; i++)
-               fprintf(f, "%02x", (unsigned char)s[i]);
-}
-
-struct artab {
-       int base;
-#          define IGNORESPACE_BIAS 1000
-       char *ascii;            /* NULL for end */
-       char *data;             /* NULL for error expected */
-} atodatatab[] = {
-       { 0, "",                        NULL, },
-       { 0, "0",                       NULL, },
-       { 0, "0x",              NULL, },
-       { 0, "0xa",             NULL, },
-       { 0, "0xab",            "\xab", },
-       { 0, "0xabc",           NULL, },
-       { 0, "0xabcd",          "\xab\xcd", },
-       { 0, "0x0123456789",    "\x01\x23\x45\x67\x89", },
-       { 0, "0x01x",           NULL, },
-       { 0, "0xabcdef",                "\xab\xcd\xef", },
-       { 0, "0xABCDEF",                "\xab\xcd\xef", },
-       { 0, "0XaBc0eEd81f",    "\xab\xc0\xee\xd8\x1f", },
-       { 0, "0XaBc0_eEd8",     "\xab\xc0\xee\xd8", },
-       { 0, "0XaBc0_",         NULL, },
-       { 0, "0X_aBc0",         NULL, },
-       { 0, "0Xa_Bc0",         NULL, },
-       { 16, "aBc0eEd8",       "\xab\xc0\xee\xd8", },
-       { 0, "0s",              NULL, },
-       { 0, "0sA",             NULL, },
-       { 0, "0sBA",            NULL, },
-       { 0, "0sCBA",           NULL, },
-       { 0, "0sDCBA",          "\x0c\x20\x40", },
-       { 0, "0SDCBA",          "\x0c\x20\x40", },
-       { 0, "0sDA==",          "\x0c", },
-       { 0, "0sDC==",          NULL, },
-       { 0, "0sDCA=",          "\x0c\x20", },
-       { 0, "0sDCB=",          NULL, },
-       { 0, "0sDCAZ",          "\x0c\x20\x19", },
-       { 0, "0sDCAa",          "\x0c\x20\x1a", },
-       { 0, "0sDCAz",          "\x0c\x20\x33", },
-       { 0, "0sDCA0",          "\x0c\x20\x34", },
-       { 0, "0sDCA9",          "\x0c\x20\x3d", },
-       { 0, "0sDCA+",          "\x0c\x20\x3e", },
-       { 0, "0sDCA/",          "\x0c\x20\x3f", },
-       { 0, "0sAbraCadabra+",  "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0s AbraCadabra+",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0sA braCadabra+",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0sAb raCadabra+",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0sAbr aCadabra+",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0sAbra Cadabra+",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0sAbraC adabra+",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0sAbraCa dabra+",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0sAbraCad abra+",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0sAbraCada bra+",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0sAbraCadab ra+",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0sAbraCadabr a+",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0sAbraCadabra +",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { IGNORESPACE_BIAS + 0, "0sAbraCadabra+ ",      "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
-       { 0, "0t",              NULL, },
-       { 0, "0tabc_xyz",               "abc_xyz", },
-       { 256, "abc_xyz",               "abc_xyz", },
-       { 0, NULL,              NULL, },
-};
-
-struct drtab {
-       char *data;     /* input; NULL for end */
-       char format;
-       int buflen;     /* -1 means big buffer */
-       int outlen;     /* -1 means strlen(ascii)+1 */
-       char *ascii;    /* NULL for error expected */
-} datatoatab[] = {
-       { "",                   'x',    -1,     -1,     NULL, },
-       { "",                   'X',    -1,     -1,     NULL, },
-       { "",                   'n',    -1,     -1,     NULL, },
-       { "0",                  'x',    -1,     -1,     "0x30", },
-       { "0",                  'x',    0,      5,      "---", },
-       { "0",                  'x',    1,      5,      "", },
-       { "0",                  'x',    2,      5,      "0", },
-       { "0",                  'x',    3,      5,      "0x", },
-       { "0",                  'x',    4,      5,      "0x3", },
-       { "0",                  'x',    5,      5,      "0x30", },
-       { "0",                  'x',    6,      5,      "0x30", },
-       { "\xab\xcd",           'x',    -1,     -1,     "0xabcd", },
-       { "\x01\x23\x45\x67\x89",       'x',    -1,     -1,     "0x0123456789", },
-       { "\xab\xcd\xef",               'x',    -1,     -1,     "0xabcdef", },
-       { "\xab\xc0\xee\xd8\x1f",       'x',    -1,     -1,     "0xabc0eed81f", },
-       { "\x01\x02",           'h',    -1,     -1,     "0x0102", },
-       { "\x01\x02\x03\x04\x05\x06",   'h',    -1, -1, "0x01020304_0506", },
-       { "\xab\xc0\xee\xd8\x1f",       16,     -1,     -1,     "abc0eed81f", },
-       { "\x0c\x20\x40",               's',    -1,     -1,     "0sDCBA", },
-       { "\x0c\x20\x40",               's',    0,      7,      "---", },
-       { "\x0c\x20\x40",               's',    1,      7,      "", },
-       { "\x0c\x20\x40",               's',    2,      7,      "0", },
-       { "\x0c\x20\x40",               's',    3,      7,      "0s", },
-       { "\x0c\x20\x40",               's',    4,      7,      "0sD", },
-       { "\x0c\x20\x40",               's',    5,      7,      "0sDC", },
-       { "\x0c\x20\x40",               's',    6,      7,      "0sDCB", },
-       { "\x0c\x20\x40",               's',    7,      7,      "0sDCBA", },
-       { "\x0c\x20\x40",               's',    8,      7,      "0sDCBA", },
-       { "\x0c",                       's',    -1,     -1,     "0sDA==", },
-       { "\x0c\x20",           's',    -1,     -1,     "0sDCA=", },
-       { "\x0c\x20\x19",               's',    -1,     -1,     "0sDCAZ", },
-       { "\x0c\x20\x1a",               's',    -1,     -1,     "0sDCAa", },
-       { "\x0c\x20\x33",               's',    -1,     -1,     "0sDCAz", },
-       { "\x0c\x20\x34",               's',    -1,     -1,     "0sDCA0", },
-       { "\x0c\x20\x3d",               's',    -1,     -1,     "0sDCA9", },
-       { "\x0c\x20\x3e",               's',    -1,     -1,     "0sDCA+", },
-       { "\x0c\x20\x3f",               's',    -1,     -1,     "0sDCA/", },
-       { "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", 's', -1, -1, "0sAbraCadabra+", },
-       { "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", 64, -1, -1, "AbraCadabra+", },
-       { NULL,                 'x',    -1,     -1,     NULL, },
-};
-
-/*
- - regress - regression-test ttodata() and datatot()
- */
-static void
-check(r, buf, n, oops, status)
-struct artab *r;
-char *buf;
-size_t n;
-err_t oops;
-int *status;
-{
-       if (oops != NULL && r->data == NULL)
-               {}                      /* error expected */
-       else if (oops != NULL) {
-               printf("`%s' gave error `%s', expecting %d `", r->ascii,
-                                               oops, strlen(r->data));
-               hexout(r->data, strlen(r->data), stdout);
-               printf("'\n");
-               *status = 1;
-       } else if (r->data == NULL) {
-               printf("`%s' gave %d `", r->ascii, n);
-               hexout(buf, n, stdout);
-               printf("', expecting error\n");
-               *status = 1;
-       } else if (n != strlen(r->data)) {
-               printf("length wrong in `%s': got %d `", r->ascii, n);
-               hexout(buf, n, stdout);
-               printf("', expecting %d `", strlen(r->data));
-               hexout(r->data, strlen(r->data), stdout);
-               printf("'\n");
-               *status = 1;
-       } else if (memcmp(buf, r->data, n) != 0) {
-               printf("`%s' gave %d `", r->ascii, n);
-               hexout(buf, n, stdout);
-               printf("', expecting %d `", strlen(r->data));
-               hexout(r->data, strlen(r->data), stdout);
-               printf("'\n");
-               *status = 1;
-       }
-       fflush(stdout);
-}
-
-static void                    /* should not return at all, in fact */
-regress(pgm)
-char *pgm;
-{
-       struct artab *r;
-       struct drtab *dr;
-       char buf[100];
-       size_t n;
-       int status = 0;
-
-       for (r = atodatatab; r->ascii != NULL; r++) {
-               int base = r->base;
-               int xbase = 0;
-
-               if ((base == 0 || base == IGNORESPACE_BIAS + 0) && r->ascii[0] == '0') {
-                       switch (r->ascii[1]) {
-                       case 'x':
-                       case 'X':
-                               xbase = 16;
-                               break;
-                       case 's':
-                       case 'S':
-                               xbase = 64;
-                               break;
-                       case 't':
-                       case 'T':
-                               xbase = 256;
-                               break;
-                       }
-               }
-               
-               if (base >= IGNORESPACE_BIAS) {
-                       base = base - IGNORESPACE_BIAS;
-                       check(r, buf, n, ttodatav(r->ascii, 0, base, buf, sizeof(buf), &n, NULL, 0, TTODATAV_IGNORESPACE), &status);
-                       if (xbase != 0)
-                               check(r, buf, n, ttodatav(r->ascii+2, 0, xbase, buf, sizeof(buf), &n, NULL, 0, TTODATAV_IGNORESPACE), &status);
-               } else {
-                       check(r, buf, n, ttodata(r->ascii, 0, base, buf, sizeof(buf), &n), &status);
-                       if (base == 64 || xbase == 64)
-                               check(r, buf, n, ttodatav(r->ascii, 0, base, buf, sizeof(buf), &n, NULL, 0, TTODATAV_IGNORESPACE), &status);
-                       if (xbase != 0) {
-                               check(r, buf, n, ttodata(r->ascii+2, 0, xbase, buf, sizeof(buf), &n), &status);
-                               if (base == 64 || xbase == 64)
-                                       check(r, buf, n, ttodatav(r->ascii+2, 0, xbase, buf, sizeof(buf), &n, NULL, 0, TTODATAV_IGNORESPACE), &status);
-                       }
-               }
-       }
-       for (dr = datatoatab; dr->data != NULL; dr++) {
-               size_t should;
-
-               strcpy(buf, "---");
-               n = datatot(dr->data, strlen(dr->data), dr->format, buf,
-                               (dr->buflen == -1) ? sizeof(buf) : dr->buflen);
-               should = (dr->ascii == NULL) ? 0 : strlen(dr->ascii) + 1;
-               if (dr->outlen != -1)
-                       should = dr->outlen;
-               if (n == 0 && dr->ascii == NULL)
-                       {}                      /* error expected */
-               else if (n == 0) {
-                       printf("`");
-                       hexout(dr->data, strlen(dr->data), stdout);
-                       printf("' %c gave error, expecting %d `%s'\n",
-                               dr->format, should, dr->ascii);
-                       status = 1;
-               } else if (dr->ascii == NULL) {
-                       printf("`");
-                       hexout(dr->data, strlen(dr->data), stdout);
-                       printf("' %c gave %d `%.*s', expecting error\n",
-                               dr->format, n, (int)n, buf);
-                       status = 1;
-               } else if (n != should) {
-                       printf("length wrong in `");
-                       hexout(dr->data, strlen(dr->data), stdout);
-                       printf("': got %d `%s'", n, buf);
-                       printf(", expecting %d `%s'\n", should, dr->ascii);
-                       status = 1;
-               } else if (strcmp(buf, dr->ascii) != 0) {
-                       printf("`");
-                       hexout(dr->data, strlen(dr->data), stdout);
-                       printf("' gave %d `%s'", n, buf);
-                       printf(", expecting %d `%s'\n", should, dr->ascii);
-                       status = 1;
-               }
-               fflush(stdout);
-       }
-       exit(status);
-}
-
-#endif /* TTODATA_MAIN */
index af09a2a..c53dac3 100644 (file)
 #include "rsa_private_key.h"
 
 #include <daemon.h>
-#include <asn1-pluto/asn1-pluto.h>
+#ifdef NEW_ASN1
+# include <asn1/asn1.h>
+# include <asn1/der_decoder.h>
+#else
+# include <asn1-pluto/asn1-pluto.h>
+#endif
 
 
 /* 
@@ -138,8 +143,7 @@ struct private_rsa_private_key_t {
        
 };
 
-#if 0 
-Not used yet, since we use plutos ASN1 stuff
+#ifdef NEW_ASN1
 /**
  * Rules for de-/encoding of a private key from/in ASN1 
  */
@@ -156,8 +160,7 @@ static asn1_rule_t rsa_private_key_rules[] = {
        {       ASN1_INTEGER, ASN1_MPZ, offsetof(private_rsa_private_key_t, coeff), 0},
        {ASN1_END, 0, 0, 0},
 };
-#endif
-
+#else
 struct {
        const char *name;
        size_t offset;
@@ -199,7 +202,7 @@ static const asn1Object_t privkeyObjects[] = {
 #define PKCS1_PRIV_KEY_PUB_EXP          3
 #define PKCS1_PRIV_KEY_COEFF            9
 #define PKCS1_PRIV_KEY_ROOF                    16
-
+#endif
 
 
 static private_rsa_private_key_t *rsa_private_key_create_empty();
@@ -447,6 +450,100 @@ static bool belongs_to(private_rsa_private_key_t *this, rsa_public_key_t *public
 }
 
 /**
+ * Check the loaded key if it is valid and usable
+ * TODO: Log errors
+ */
+static status_t check(private_rsa_private_key_t *this)
+{
+       mpz_t t, u, q1;
+       status_t status = SUCCESS;
+       
+       /* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets.
+       * We actually require more (for security).
+       */
+       if (this->k < 512/8)
+       {
+               return FAILED;
+       }
+       
+       /* we picked a max modulus size to simplify buffer allocation */
+       if (this->k > 8192/8)
+       {
+               return FAILED;
+       }
+       
+       mpz_init(t);
+       mpz_init(u);
+       mpz_init(q1);
+       
+       /* check that n == p * q */
+       mpz_mul(u, this->p, this->q);
+       if (mpz_cmp(u, this->n) != 0)
+       {
+               status = FAILED;
+       }
+       
+       /* check that e divides neither p-1 nor q-1 */
+       mpz_sub_ui(t, this->p, 1);
+       mpz_mod(t, t, this->e);
+       if (mpz_cmp_ui(t, 0) == 0)
+       {
+               status = FAILED;
+       }
+       
+       mpz_sub_ui(t, this->q, 1);
+       mpz_mod(t, t, this->e);
+       if (mpz_cmp_ui(t, 0) == 0)
+       {
+               status = FAILED;
+       }
+       
+       /* check that d is e^-1 (mod lcm(p-1, q-1)) */
+       /* see PKCS#1v2, aka RFC 2437, for the "lcm" */
+       mpz_sub_ui(q1, this->q, 1);
+       mpz_sub_ui(u, this->p, 1);
+       mpz_gcd(t, u, q1);              /* t := gcd(p-1, q-1) */
+       mpz_mul(u, u, q1);              /* u := (p-1) * (q-1) */
+       mpz_divexact(u, u, t);  /* u := lcm(p-1, q-1) */
+       
+       mpz_mul(t, this->d, this->e);
+       mpz_mod(t, t, u);
+       if (mpz_cmp_ui(t, 1) != 0)
+       {
+               status = FAILED;
+       }
+       
+       /* check that exp1 is d mod (p-1) */
+       mpz_sub_ui(u, this->p, 1);
+       mpz_mod(t, this->d, u);
+       if (mpz_cmp(t, this->exp1) != 0)
+       {
+               status = FAILED;
+       }
+       
+       /* check that exp2 is d mod (q-1) */
+       mpz_sub_ui(u, this->q, 1);
+       mpz_mod(t, this->d, u);
+       if (mpz_cmp(t, this->exp2) != 0)
+       {
+               status = FAILED;
+       }
+       
+       /* check that coeff is (q^-1) mod p */
+       mpz_mul(t, this->coeff, this->q);
+       mpz_mod(t, t, this->p);
+       if (mpz_cmp_ui(t, 1) != 0)
+       {
+               status = FAILED;
+       }
+       
+       mpz_clear(t);
+       mpz_clear(u);
+       mpz_clear(q1);
+       return status;
+}
+
+/**
  * Implementation of rsa_private_key.clone.
  */
 static rsa_private_key_t* _clone(private_rsa_private_key_t *this)
@@ -595,9 +692,7 @@ rsa_private_key_t *rsa_private_key_create(size_t key_size)
        return &this->public;
 }
 
-
-#if 0 
-NOT used yet, since we use plutos ASN1 parser for now
+#ifdef NEW_ASN1
 /*
  * see header
  */
@@ -627,98 +722,20 @@ rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t chunk)
                return NULL;
        }
        this->k = (mpz_sizeinbase(this->n, 2) + 7) / 8;
-       return &this->public;
-}
-#endif
-
-static status_t check(private_rsa_private_key_t *this)
-{
-       mpz_t t, u, q1;
-       status_t status = SUCCESS;
-       
-       /* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets.
-        * We actually require more (for security).
-        */
-       if (this->k < 512/8)
-               return FAILED;
-       
-       /* we picked a max modulus size to simplify buffer allocation */
-       if (this->k > 8192/8)
-               return FAILED;
-       
-       mpz_init(t);
-       mpz_init(u);
-       mpz_init(q1);
-       
-       /* check that n == p * q */
-       mpz_mul(u, this->p, this->q);
-       if (mpz_cmp(u, this->n) != 0)
-       {
-               status = FAILED;
-       }
-       
-       /* check that e divides neither p-1 nor q-1 */
-       mpz_sub_ui(t, this->p, 1);
-       mpz_mod(t, t, this->e);
-       if (mpz_cmp_ui(t, 0) == 0)
-       {
-               status = FAILED;
-       }
-       
-       mpz_sub_ui(t, this->q, 1);
-       mpz_mod(t, t, this->e);
-       if (mpz_cmp_ui(t, 0) == 0)
-       {
-               status = FAILED;
-       }
-       
-       /* check that d is e^-1 (mod lcm(p-1, q-1)) */
-       /* see PKCS#1v2, aka RFC 2437, for the "lcm" */
-       mpz_sub_ui(q1, this->q, 1);
-       mpz_sub_ui(u, this->p, 1);
-       mpz_gcd(t, u, q1);              /* t := gcd(p-1, q-1) */
-       mpz_mul(u, u, q1);              /* u := (p-1) * (q-1) */
-       mpz_divexact(u, u, t);  /* u := lcm(p-1, q-1) */
-       
-       mpz_mul(t, this->d, this->e);
-       mpz_mod(t, t, u);
-       if (mpz_cmp_ui(t, 1) != 0)
-       {
-               status = FAILED;
-       }
        
-       /* check that exp1 is d mod (p-1) */
-       mpz_sub_ui(u, this->p, 1);
-       mpz_mod(t, this->d, u);
-       if (mpz_cmp(t, this->exp1) != 0)
-       {
-               status = FAILED;
-       }
-       
-       /* check that exp2 is d mod (q-1) */
-       mpz_sub_ui(u, this->q, 1);
-       mpz_mod(t, this->d, u);
-       if (mpz_cmp(t, this->exp2) != 0)
+       if (check(this) != SUCCESS)
        {
-               status = FAILED;
+               destroy(this);
+               return NULL;
        }
-       
-       /* check that coeff is (q^-1) mod p */
-       mpz_mul(t, this->coeff, this->q);
-       mpz_mod(t, t, this->p);
-       if (mpz_cmp_ui(t, 1) != 0)
+       else
        {
-               status = FAILED;
+               return &this->public;
        }
-       
-       mpz_clear(t);
-       mpz_clear(u);
-       mpz_clear(q1);
-       return status;
 }
-
+#else
 /*
- *  Parses a PKCS#1 private key
+ * see header
  */
 rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t blob)
 {
@@ -745,6 +762,7 @@ rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t blob)
        {
                if (!extract_object(privkeyObjects, &objectID, &object, &level, &ctx))
                {
+                       destroy(this);
                        return FALSE;
                }
                if (objectID == PKCS1_PRIV_KEY_VERSION)
@@ -765,6 +783,9 @@ rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t blob)
                }
                objectID++;
        }
+       
+       this->k = (mpz_sizeinbase(this->n, 2) + 7) / 8;
+       
        if (check(this) != SUCCESS)
        {
                destroy(this);
@@ -775,9 +796,11 @@ rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t blob)
                return &this->public;
        }
 }
+#endif
 
 /*
  * see header
+ * TODO: PEM files
  */
 rsa_private_key_t *rsa_private_key_create_from_file(char *filename, char *passphrase)
 {
index 5b85f52..61739dd 100644 (file)
@@ -37,6 +37,7 @@
  * hash algorithm OIDs. These also contain
  * the length of the following hash.
  * These values are also used in rsa_private_key.c.
+ * TODO: We may move them in asn1 sometime...
  */
 
 u_int8_t md2_oid[] = {