[svn] ksba - r288 - in trunk: . src tests

svn author wk cvs at cvs.gnupg.org
Fri Feb 22 16:46:35 CET 2008


Author: wk
Date: 2008-02-22 16:46:34 +0100 (Fri, 22 Feb 2008)
New Revision: 288

Modified:
   trunk/NEWS
   trunk/TODO
   trunk/src/ChangeLog
   trunk/src/keyinfo.c
   trunk/tests/cert-basic.c
Log:
Support DSA


[The diff below has been truncated]

Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog	2008-02-21 10:22:28 UTC (rev 287)
+++ trunk/src/ChangeLog	2008-02-22 15:46:34 UTC (rev 288)
@@ -1,3 +1,16 @@
+2008-02-22  Werner Koch  <wk at g10code.com>
+
+	* keyinfo.c (pkalgo_t): New.
+	(algo_table_s): Add fields PARMELEM_STRING and
+	PARMCTRL_STRING. repalce IS-ECC by PKALGO. Adjust all tables and
+	users of IS_ECC.  Add DSA parameter description.
+	(TLV_LENGTH): Add PREFIX arg and change all callers.
+	(_ksba_keyinfo_to_sexp): Parse parameters.
+	(oid_from_buffer): Replace R_IS_ECC by R_PKALGO and allow for DSA.
+	(_ksba_keyinfo_from_sexp): Revamp to support DSA.
+	(sig_algo_table): Add dsaWithRIPEMD160, dsaWithSha224 and
+	dsaWithSha256.
+
 2008-02-21  Werner Koch  <wk at g10code.com>
 
 	* der-encoder.c (_ksba_der_write_algorithm_identifier): Add hack
@@ -972,7 +985,7 @@
 	(ksba_cert_get_subject): Ditto.
 	
 
- Copyright 2001, 2002, 2003, 2004, 2005 g10 Code GmbH
+ Copyright 2001, 2002, 2003, 2004, 2005, 2008 g10 Code GmbH
 
  This file is free software; as a special exception the author gives
  unlimited permission to copy and/or distribute it, with or without

Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2008-02-21 10:22:28 UTC (rev 287)
+++ trunk/NEWS	2008-02-22 15:46:34 UTC (rev 288)
@@ -3,7 +3,9 @@
 
  * Write smimeCapabilities according to RFC3851 to help Mozilla.
 
+ * Support DSA.
 
+
 Noteworthy changes in version 1.0.3 (2008-02-12)
 ------------------------------------------------
 

Modified: trunk/TODO
===================================================================
--- trunk/TODO	2008-02-21 10:22:28 UTC (rev 287)
+++ trunk/TODO	2008-02-22 15:46:34 UTC (rev 288)
@@ -32,11 +32,9 @@
    retrieved by online means.
 ** cant't handle unprotected attributes
    e.g. for counter signatures.  Not needed in Aegypten.
-** Support DSA
 
 
 * src/keyinfo.c
-** Extract DSA parameters
 ** Do we need to support BER encoded stuff?
 
 * src/time.c

Modified: trunk/src/keyinfo.c
===================================================================
--- trunk/src/keyinfo.c	2008-02-21 10:22:28 UTC (rev 287)
+++ trunk/src/keyinfo.c	2008-02-22 15:46:34 UTC (rev 288)
@@ -1,5 +1,5 @@
 /* keyinfo.c - Parse and build a keyInfo structure
- *      Copyright (C) 2001, 2002, 2007 g10 Code GmbH
+ *      Copyright (C) 2001, 2002, 2007, 2008 g10 Code GmbH
  *
  * This file is part of KSBA.
  *
@@ -35,45 +35,59 @@
 #include "convert.h"
 #include "ber-help.h"
 
+
+/* Constants used for the public key algorithms.  */
+typedef enum 
+  {
+    PKALGO_RSA,
+    PKALGO_DSA,
+    PKALGO_ECC
+  }
+pkalgo_t;
+
+
 struct algo_table_s {
   const char *oidstring;
   const unsigned char *oid;  /* NULL indicattes end of table */
   int                  oidlen;
   int supported;
-  int is_ecc;
+  pkalgo_t pkalgo;
   const char *algo_string;
   const char *elem_string; /* parameter name or '-' */
   const char *ctrl_string; /* expected tag values (value > 127 are raw data)*/
+  const char *parmelem_string; /* parameter name or '-'. */
+  const char *parmctrl_string; /* expected tag values.  */
   const char *digest_string; /* The digest algo if included in the OID. */
 };
 
+
+
 static struct algo_table_s pk_algo_table[] = {
 
   { /* iso.member-body.us.rsadsi.pkcs.pkcs-1.1 */
     "1.2.840.113549.1.1.1", /* rsaEncryption (RSAES-PKCA1-v1.5) */ 
     "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01", 9, 
-    1, 0, "rsa", "-ne", "\x30\x02\x02" },
+    1, PKALGO_RSA, "rsa", "-ne", "\x30\x02\x02" },
 
   { /* iso.member-body.us.rsadsi.pkcs.pkcs-1.7 */
     "1.2.840.113549.1.1.7", /* RSAES-OAEP */ 
     "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x07", 9, 
-    0, 0, "rsa", "-ne", "\x30\x02\x02"}, /* (patent problems) */
+    0, PKALGO_RSA, "rsa", "-ne", "\x30\x02\x02"}, /* (patent problems) */
 
   { /* */
     "2.5.8.1.1", /* rsa (ambiguous due to missing padding rules)*/
     "\x55\x08\x01\x01", 4, 
-    1, 0, "ambiguous-rsa", "-ne", "\x30\x02\x02" },
+    1, PKALGO_RSA, "ambiguous-rsa", "-ne", "\x30\x02\x02" },
 
   { /* iso.member-body.us.x9-57.x9cm.1 */
     "1.2.840.10040.4.1", /*  dsa */
     "\x2a\x86\x48\xce\x38\x04\x01", 7, 
-    1, 0, "dsa", "y", "\x02" }, 
-  /* FIXME: Need code to extract p,q,g from the parameters */
+    1, PKALGO_DSA, "dsa", "y", "\x02", "-pqg", "\x30\x02\x02\x02" }, 
  
   { /* iso.member-body.us.ansi-x9-62.2.1 */
     "1.2.840.10045.2.1", /*  ecPublicKey */
     "\x2a\x86\x48\xce\x3d\x02\x01", 7, 
-    1, 1,"ecc", "q", "\x80" }, 
+    1, PKALGO_ECC, "ecc", "q", "\x80" }, 
 
   {NULL}
 };
@@ -83,85 +97,101 @@
   {  /* iso.member-body.us.rsadsi.pkcs.pkcs-1.5 */
     "1.2.840.113549.1.1.5", /* sha1WithRSAEncryption */ 
     "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05", 9, 
-    1, 0, "rsa", "s", "\x82", "sha1" },
+    1, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "sha1" },
   { /* iso.member-body.us.rsadsi.pkcs.pkcs-1.4 */
     "1.2.840.113549.1.1.4", /* md5WithRSAEncryption */ 
     "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x04", 9, 
-    1, 0, "rsa", "s", "\x82", "md5" },
+    1, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "md5" },
   { /* iso.member-body.us.rsadsi.pkcs.pkcs-1.2 */
     "1.2.840.113549.1.1.2", /* md2WithRSAEncryption */ 
     "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x02", 9, 
-    0, 0, "rsa", "s", "\x82", "md2" },
+    0, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "md2" },
+  { /* iso.member-body.us.x9-57.x9cm.1 */
+    "1.2.840.10040.4.3", /* dsa */
+    "\x2a\x86\x48\xce\x38\x04\x01", 7, 
+    1, PKALGO_DSA, "dsa", "-rs", "\x30\x02\x02" }, 
   { /* iso.member-body.us.x9-57.x9cm.3 */
     "1.2.840.10040.4.3", /*  dsaWithSha1 */
     "\x2a\x86\x48\xce\x38\x04\x03", 7, 
-    1, 0, "dsa", "-rs", "\x30\x02\x02", "sha1" }, 
+    1, PKALGO_DSA, "dsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha1" }, 
+  { /* Teletrust signature algorithm.  */
+    "1.3.36.8.5.1.2.2", /* dsaWithRIPEMD160 */
+    "\x06\x07\x2B\x24\x08\x05\x01\x02\x02", 9,
+    1, PKALGO_DSA, "dsa", "-rs", "\x30\x02\x02", NULL, NULL, "rmd160" }, 
+  { /* NIST Algorithm */
+    "2.16.840.1.101.3.4.3.1", /* dsaWithSha224 */
+    "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x03\x01", 11,
+    1, PKALGO_DSA, "dsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha224" }, 
+  { /* NIST Algorithm (the draft also used .1 but we better use .2) */
+    "2.16.840.1.101.3.4.3.2", /* dsaWithSha256 */
+    "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x03\x01", 11,
+    1, PKALGO_DSA, "dsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha256" }, 
 
   { /* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-sha1 */
     "1.2.840.10045.4.1", /*  ecdsa */
     "\x2a\x86\x48\xce\x3d\x04\x01", 7, 
-    1, 1, "ecdsa", "-rs", "\x30\x02\x02", "sha1" }, 
+    1, PKALGO_ECC, "ecdsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha1" }, 
 
   { /* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-specified */
     "1.2.840.10045.4.3", 
     "\x2a\x86\x48\xce\x3d\x04\x03", 7, 
-    1, 1, "ecdsa", "-rs", "\x30\x02\x02", NULL }, 
+    1, PKALGO_ECC, "ecdsa", "-rs", "\x30\x02\x02", NULL, NULL, NULL }, 
   /* The digest algorithm is given by the parameter.  */ 
 
 
   { /* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-sha224 */
     "1.2.840.10045.4.3.1", 
     "\x2a\x86\x48\xce\x3d\x04\x03\x01", 8, 
-    1, 1, "ecdsa", "-rs", "\x30\x02\x02", "sha224" }, 
+    1, PKALGO_ECC, "ecdsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha224" }, 
 
   { /* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-sha256 */
     "1.2.840.10045.4.3.2", 
     "\x2a\x86\x48\xce\x3d\x04\x03\x02", 8, 
-    1, 1, "ecdsa", "-rs", "\x30\x02\x02", "sha256" }, 
+    1, PKALGO_ECC, "ecdsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha256" }, 
 
   { /* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-sha384 */
     "1.2.840.10045.4.3.3", 
     "\x2a\x86\x48\xce\x3d\x04\x03\x03", 8, 
-    1, 1, "ecdsa", "-rs", "\x30\x02\x02", "sha384" }, 
+    1, PKALGO_ECC, "ecdsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha384" }, 
 
   { /* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-sha512 */
     "1.2.840.10045.4.3.4", 
     "\x2a\x86\x48\xce\x3d\x04\x03\x04", 8, 
-    1, 1, "ecdsa", "-rs", "\x30\x02\x02", "sha512" }, 
+    1, PKALGO_ECC, "ecdsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha512" }, 
 
   { /* iso.member-body.us.rsadsi.pkcs.pkcs-1.1 */
     "1.2.840.113549.1.1.1", /* rsaEncryption used without hash algo*/ 
     "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01", 9, 
-    1, 0, "rsa", "s", "\x82" },
+    1, PKALGO_RSA, "rsa", "s", "\x82" },
   { /* from NIST's OIW - actually belongs in a pure hash table */
     "1.3.14.3.2.26",  /* sha1 */
     "\x2B\x0E\x03\x02\x1A", 5,
-    0, 0, "sha-1", "", "", "sha1" },
+    0, PKALGO_RSA, "sha-1", "", "", NULL, NULL, "sha1" },
 
   { /* As used by telesec cards */
     "1.3.36.3.3.1.2",  /* rsaSignatureWithripemd160 */
     "\x2b\x24\x03\x03\x01\x02", 6,
-    1, 0, "rsa", "s", "\x82", "rmd160" },
+    1, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "rmd160" },
 
   { /* from NIST's OIW - used by TU Darmstadt */
     "1.3.14.3.2.29",  /* sha-1WithRSAEncryption */
     "\x2B\x0E\x03\x02\x1D", 5,
-    1, 0, "rsa", "s", "\x82", "sha1" },
+    1, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "sha1" },
 
   { /* from PKCS#1  */
     "1.2.840.113549.1.1.11", /* sha256WithRSAEncryption */
     "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b", 9,
-    1, 0, "rsa", "s", "\x82", "sha256" },
+    1, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "sha256" },
 
   { /* from PKCS#1  */
     "1.2.840.113549.1.1.12", /* sha384WithRSAEncryption */
     "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0c", 9,
-    1, 0, "rsa", "s", "\x82", "sha384" },
+    1, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "sha384" },
 
   { /* from PKCS#1  */
     "1.2.840.113549.1.1.13", /* sha512WithRSAEncryption */
     "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0d", 9,
-    1, 0, "rsa", "s", "\x82", "sha512" },
+    1, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "sha512" },
 
   {NULL}
 };
@@ -170,7 +200,7 @@
   { /* iso.member-body.us.rsadsi.pkcs.pkcs-1.1 */
     "1.2.840.113549.1.1.1", /* rsaEncryption (RSAES-PKCA1-v1.5) */ 
     "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01", 9, 
-    1, 0, "rsa", "a", "\x82" },
+    1, PKALGO_RSA, "rsa", "a", "\x82" },
   {NULL}
 };
 
@@ -220,10 +250,10 @@
 };
 
 
-#define TLV_LENGTH() do {         \
-  if (!derlen)                    \
+#define TLV_LENGTH(prefix) do {         \
+  if (!prefix ## len)                    \
     return gpg_error (GPG_ERR_INV_KEYINFO);  \
-  c = *der++; derlen--;           \
+  c = *(prefix)++; prefix ## len--;           \
   if (c == 0x80)                  \
     return gpg_error (GPG_ERR_NOT_DER_ENCODED);  \
   if (c == 0xff)                  \
@@ -238,32 +268,17 @@
       for (len=0; count; count--) \
         {                         \
           len <<= 8;              \
-          if (!derlen)            \
+          if (!prefix ## len)            \
             return gpg_error (GPG_ERR_BAD_BER);\
-          c = *der++; derlen--;   \
+          c = *(prefix)++; prefix ## len--;   \
           len |= c & 0xff;        \
         }                         \
     }                             \
-  if (len > derlen)               \
+  if (len > prefix ## len)               \
     return gpg_error (GPG_ERR_INV_KEYINFO);  \
 } while (0)
 
 
-#if 0
-static void
-dump_hex (const unsigned char *p, size_t n)
-{
-  if (!p)
-    fputs (" none", stderr);
-  else
-    {
-      for (; n; n--, p++)
-        fprintf (stderr, " %02X", *p);
-    }
-}
-#endif
-
-
 /* Given a string BUF of length BUFLEN with either the name of an ECC
    curve or its OID in dotted form return the DER encoding of the OID.
    The caller must free the result.  On error NULL is returned.  */
@@ -328,7 +343,7 @@
   c = *der++; derlen--;
   if ( c != 0x30 )
     return gpg_error (GPG_ERR_UNEXPECTED_TAG); /* not a SEQUENCE */
-  TLV_LENGTH(); 
+  TLV_LENGTH(der); 
   seqlen = len;
   startseq = der;
 
@@ -338,7 +353,7 @@
   c = *der++; derlen--; 
   if ( c != 0x06 )
     return gpg_error (GPG_ERR_UNEXPECTED_TAG); /* not an OBJECT IDENTIFIER */
-  TLV_LENGTH();
+  TLV_LENGTH(der);
 
   /* der does now point to an oid of length LEN */
   *r_pos = der - start;
@@ -376,7 +391,7 @@
           /*  This is an octet string parameter and we need it.  */
           if (r_parm_type)
             *r_parm_type = TYPE_OCTET_STRING;
-          TLV_LENGTH();
+          TLV_LENGTH(der);
           *r_parm_pos = der - start;
           *r_parm_len = len;
           seqlen -= der - startparm;
@@ -389,7 +404,7 @@
           /*  This is an object identifier.  */
           if (r_parm_type)
             *r_parm_type = TYPE_OBJECT_ID;
-          TLV_LENGTH();
+          TLV_LENGTH(der);
           *r_parm_pos = der - start;
           *r_parm_len = len;
           seqlen -= der - startparm;
@@ -402,7 +417,7 @@
           /*  This is a sequence. */
           if (r_parm_type)
             *r_parm_type = TYPE_SEQUENCE;
-          TLV_LENGTH();
+          TLV_LENGTH(der);
           *r_parm_pos = startparm - start;
           *r_parm_len = len + (der - startparm);
           seqlen -= der - startparm;
@@ -413,7 +428,7 @@
       else
         {
 /*            printf ("parameter: with tag %02x - ignored\n", c); */
-          TLV_LENGTH();
+          TLV_LENGTH(der);
           seqlen -= der - startparm;
           /* skip the value */
           der += len;
@@ -438,7 +453,7 @@
         ; /* OCTECT STRING */
       else
         return gpg_error (GPG_ERR_UNEXPECTED_TAG); /* not a BIT STRING */
-      TLV_LENGTH();
+      TLV_LENGTH(der);
     }
 
   *r_nread = der - start;
@@ -612,8 +627,6 @@
                     parameters   ANY DEFINED BY algorithm OPTIONAL }
                  publicKey  BIT STRING }
   
-  We only allow parameters == NULL.
-
   The function parses this structure and create a SEXP suitable to be
   used as a public key in Libgcrypt.  The S-Exp will be returned in a
   string which the caller must free.  
@@ -631,6 +644,8 @@
   char *parm_oid = NULL;
   int algoidx;
   int is_bitstr;
+  const unsigned char *parmder = NULL;
+  size_t parmderlen = 0;
   const unsigned char *ctrl;
   const char *elem;
   struct stringbuf sb;
@@ -643,7 +658,7 @@
   c = *der++; derlen--;
   if ( c != 0x30 )
     return gpg_error (GPG_ERR_UNEXPECTED_TAG); /* not a SEQUENCE */
-  TLV_LENGTH();
+  TLV_LENGTH(der);
   /* and now the inner part */
   err = get_algorithm (1, der, derlen, &nread, &off, &len, &is_bitstr,
                        &parm_off, &parm_len, &parm_type);
@@ -662,9 +677,13 @@
   if (!pk_algo_table[algoidx].supported)
     return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
 
-
   if (parm_off && parm_len && parm_type == TYPE_OBJECT_ID)
     parm_oid = ksba_oid_to_str (der+parm_off, parm_len);
+  else if (parm_off && parm_len)
+    {
+      parmder = der + parm_off;
+      parmderlen = parm_len;
+    }
 
   der += nread;
   derlen -= nread;
@@ -694,7 +713,7 @@
   put_stringbuf_sexp (&sb, pk_algo_table[algoidx].algo_string);
 
   /* Insert the curve name for ECC. */
-  if (pk_algo_table[algoidx].is_ecc && parm_oid)
+  if (pk_algo_table[algoidx].pkalgo == PKALGO_ECC && parm_oid)
     {
       put_stringbuf (&sb, "(");
       put_stringbuf_sexp (&sb, "curve");
@@ -702,6 +721,56 @@
       put_stringbuf (&sb, ")");
     }
 
+  /* If parameters are given and we have a description for them, parse
+     them. */
+  if (parmder && parmderlen 
+      && pk_algo_table[algoidx].parmelem_string
+      && pk_algo_table[algoidx].parmctrl_string)
+    {
+      elem = pk_algo_table[algoidx].parmelem_string; 
+      ctrl = pk_algo_table[algoidx].parmctrl_string; 
+      for (; *elem; ctrl++, elem++)
+        {
+          int is_int;
+          
+          if ( (*ctrl & 0x80) && !elem[1] )
+            {
+              /* Hack to allow reading a raw value.  */
+              is_int = 1;
+              len = parmderlen;
+            }
+          else
+            {
+              if (!parmderlen)
+                {
+                  xfree (parm_oid);
+                  return gpg_error (GPG_ERR_INV_KEYINFO);
+                }
+              c = *parmder++; parmderlen--;
+              if ( c != *ctrl )
+                {
+                  xfree (parm_oid);
+                  return gpg_error (GPG_ERR_UNEXPECTED_TAG);
+                }
+              is_int = c == 0x02;
+              TLV_LENGTH (parmder);
+            }
+          if (is_int && *elem != '-')  /* Take this integer.  */
+            { 
+              char tmp[2];
+              
+              put_stringbuf (&sb, "(");
+              tmp[0] = *elem; tmp[1] = 0;
+              put_stringbuf_sexp (&sb, tmp);
+              put_stringbuf_mem_sexp (&sb, parmder, len);
+              parmder += len;
+              parmderlen -= len;
+              put_stringbuf (&sb, ")");
+            }
+        }
+    }
+
+
   /* FIXME: We don't release the stringbuf in case of error
      better let the macro jump to a label */
   elem = pk_algo_table[algoidx].elem_string; 
@@ -730,7 +799,7 @@
               return gpg_error (GPG_ERR_UNEXPECTED_TAG);
             }
           is_int = c == 0x02;
-          TLV_LENGTH ();
+          TLV_LENGTH (der);
         }
       if (is_int && *elem != '-')  /* Take this integer.  */
         { 
@@ -758,18 +827,14 @@
 
 /* Match the algorithm string given in BUF which is of length BUFLEN
    with the known algorithms from our table and returns the table
-   entries for the DER encoded OID.
-
-   FIXME: We restrict this for now to RSA and ECC because the code
-   using this function is not yet prepared to handle other
-   algorithms.  */
+   entries for the DER encoded OID.  */
 static const unsigned char *
 oid_from_buffer (const unsigned char *buf, int buflen, int *oidlen,
-                 int *r_is_ecc)
+                 pkalgo_t *r_pkalgo)
 {
   int i;
 
-  /* ignore a leading "oid." string */
+  /* Ignore an optional "oid." prefix. */
   if (buflen > 4 && buf[3] == '.' && digitp (buf+4)
       && ((buf[0] == 'o' && buf[1] == 'i' && buf[2] == 'd')
           ||(buf[0] == 'O' && buf[1] == 'I' && buf[2] == 'D')))
@@ -778,7 +843,7 @@
       buflen -= 4;
     }
 
-  /* and scan the table */
+  /* Scan the table. */
   for (i=0; pk_algo_table[i].oid; i++)
     {
       if (!pk_algo_table[i].supported)
@@ -792,12 +857,8 @@




More information about the Gnupg-commits mailing list