[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