-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].
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.
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
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:
#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
}
}
+ /* 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,
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 */
if (rdata_len < 1) {
SILC_LOG_DEBUG(("Malformed object identifier value"));
+ SILC_ASN1_VA_FREE(opts, oidstr);
ret = FALSE;
goto fail;
}
if (rdata_len < 2) {
SILC_LOG_DEBUG(("Malformed bit string value"));
+ SILC_ASN1_VA_FREE(opts, d);
ret = FALSE;
goto fail;
}
if (rdata_len < 1) {
SILC_LOG_DEBUG(("Malformed UTC time value"));
+ SILC_ASN1_VA_FREE(opts, t);
ret = FALSE;
goto fail;
}
if (rdata_len < 1) {
SILC_LOG_DEBUG(("Malformed generalized time value"));
+ SILC_ASN1_VA_FREE(opts, t);
ret = FALSE;
goto fail;
}
/* 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;
}
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;
}
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);
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 */
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
#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. */
SilcBool val = TRUE;
int i;
unsigned char *str;
- SilcUInt32 str_len;
+ SilcUInt32 str_len, tmpint;
char tmp[32];
SilcRng rng;
SilcMPInt mpint, mpint2;
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);
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"
/* 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;
}
/* 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),
SILC_ASN1_END, SILC_ASN1_END))
goto err;
- silc_mp_uninit(&version);
silc_mp_uninit(&n);
silc_mp_uninit(&e);
silc_mp_uninit(&e);
SilcAsn1 asn1;
SilcBufferStruct alg_key;
RsaPrivateKey *privkey;
+ SilcUInt32 ver;
if (!ret_private_key)
return FALSE;
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),
SILC_ASN1_END, SILC_ASN1_END))
goto err;
+ if (ver != 0)
+ goto err;
+
/* Set key length */
privkey->bits = silc_mp_sizeinbase(&privkey->n, 2);
RsaPrivateKey *key = private_key;
SilcAsn1 asn1;
SilcBufferStruct alg_key;
- SilcMPInt version;
unsigned char *ret;
asn1 = silc_asn1_alloc();
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),
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);