summaryrefslogtreecommitdiffstats
path: root/libtomcrypt
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2010-07-19 20:10:26 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2010-07-19 20:10:26 +0200
commit56eb45f752baa978a9ea3573faee44857678597d (patch)
tree3c7da78ba84669d0f988b98450e4e55779dfcb41 /libtomcrypt
parent035b7bf3544ab9927dc2d64cf1e3214237ff0f71 (diff)
downloadcryptodev-linux-56eb45f752baa978a9ea3573faee44857678597d.tar.gz
cryptodev-linux-56eb45f752baa978a9ea3573faee44857678597d.tar.xz
cryptodev-linux-56eb45f752baa978a9ea3573faee44857678597d.zip
Public Keys are being exported to SubjectPublicKeyInfo format, instead of custom formats. For RSA keys the PKCS #1 format can be used as well.
Diffstat (limited to 'libtomcrypt')
-rw-r--r--libtomcrypt/headers/tomcrypt_hash.h6
-rw-r--r--libtomcrypt/headers/tomcrypt_pk.h23
-rw-r--r--libtomcrypt/misc/pk_get_oid.c40
-rw-r--r--libtomcrypt/pk/asn1/der/bit/der_decode_bit_string.c8
-rw-r--r--libtomcrypt/pk/asn1/der/bit/der_encode_bit_string.c7
-rw-r--r--libtomcrypt/pk/asn1/der/sequence/der_decode_subject_public_key_info.c97
-rw-r--r--libtomcrypt/pk/asn1/der/sequence/der_encode_subject_public_key_info.c69
-rw-r--r--libtomcrypt/pk/dsa/dsa_export.c41
-rw-r--r--libtomcrypt/pk/dsa/dsa_import.c49
-rw-r--r--libtomcrypt/pk/rsa/rsa_export.c23
-rw-r--r--libtomcrypt/pk/rsa/rsa_import.c43
11 files changed, 334 insertions, 72 deletions
diff --git a/libtomcrypt/headers/tomcrypt_hash.h b/libtomcrypt/headers/tomcrypt_hash.h
index 5eaa97c..417e481 100644
--- a/libtomcrypt/headers/tomcrypt_hash.h
+++ b/libtomcrypt/headers/tomcrypt_hash.h
@@ -8,11 +8,5 @@ int hash_memory(int hash,
int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen,
const unsigned char *in, unsigned long inlen, ...);
-typedef struct Oid {
- unsigned long OID[16];
- /** Length of DER encoding */
- unsigned long OIDlen;
-} oid_st;
-
int hash_get_oid(int hash, oid_st* st);
diff --git a/libtomcrypt/headers/tomcrypt_pk.h b/libtomcrypt/headers/tomcrypt_pk.h
index c8279ff..fa6030e 100644
--- a/libtomcrypt/headers/tomcrypt_pk.h
+++ b/libtomcrypt/headers/tomcrypt_pk.h
@@ -5,6 +5,18 @@ enum {
PK_PRIVATE=1
};
+enum {
+ PKA_RSA,
+ PKA_DSA
+};
+
+typedef struct Oid {
+ unsigned long OID[16];
+ /** Length of DER encoding */
+ unsigned long OIDlen;
+} oid_st;
+
+int pk_get_oid(int pk, oid_st *st);
int rand_prime(mp_int *N, long len);
/* ---- RSA ---- */
@@ -210,12 +222,21 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
ltc_asn1_list *list, unsigned long outlen, int ordered);
-
+
#define der_decode_sequence(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 1)
int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
unsigned long *outlen);
+/* SUBJECT PUBLIC KEY INFO */
+int der_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen,
+ unsigned int algorithm, void* public_key, unsigned long public_key_len,
+ unsigned long parameters_type, void* parameters, unsigned long parameters_len);
+
+int der_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen,
+ unsigned int algorithm, void* public_key, unsigned long* public_key_len,
+ unsigned long parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len);
+
/* SET */
#define der_decode_set(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 0)
#define der_length_set der_length_sequence
diff --git a/libtomcrypt/misc/pk_get_oid.c b/libtomcrypt/misc/pk_get_oid.c
new file mode 100644
index 0000000..197d7ae
--- /dev/null
+++ b/libtomcrypt/misc/pk_get_oid.c
@@ -0,0 +1,40 @@
+/* LibTomCrypt, modular cryptographic library
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ */
+#include "tomcrypt.h"
+
+static const oid_st rsa_oid = {
+ .OIDlen = 7,
+ .OID = { 1, 2, 840, 113549, 1, 1, 1 },
+};
+
+static const oid_st dsa_oid = {
+ .OIDlen = 6,
+ .OID = { 1, 2, 840, 10040, 4, 1 },
+};
+
+/*
+ Returns the OID of the public key algorithm.
+ @return CRYPT_OK if valid
+*/
+int pk_get_oid(int pk, oid_st *st)
+{
+ switch (pk) {
+ case PKA_RSA:
+ memcpy(st, &rsa_oid, sizeof(*st));
+ break;
+ case PKA_DSA:
+ memcpy(st, &dsa_oid, sizeof(*st));
+ break;
+ default:
+ return CRYPT_INVALID_ARG;
+ }
+ return CRYPT_OK;
+}
+
diff --git a/libtomcrypt/pk/asn1/der/bit/der_decode_bit_string.c b/libtomcrypt/pk/asn1/der/bit/der_decode_bit_string.c
index d126df3..c9f6368 100644
--- a/libtomcrypt/pk/asn1/der/bit/der_decode_bit_string.c
+++ b/libtomcrypt/pk/asn1/der/bit/der_decode_bit_string.c
@@ -18,11 +18,13 @@
#ifdef LTC_DER
+#define setbit(v, n) (v=((unsigned char)(v) | (1U << (unsigned char)(n))))
+
/**
Store a BIT STRING
@param in The DER encoded BIT STRING
@param inlen The size of the DER BIT STRING
- @param out [out] The array of bits stored (one per char)
+ @param out [out] The array of bits stored (8 per char)
@param outlen [in/out] The number of bits stored
@return CRYPT_OK if successful
*/
@@ -84,7 +86,9 @@ int der_decode_bit_string(const unsigned char *in, unsigned long inlen,
/* decode/store the bits */
for (y = 0; y < blen; y++) {
- out[y] = (in[x] & (1 << (7 - (y & 7)))) ? 1 : 0;
+ if (in[x] & (1 << (7 - (y & 7)))) {
+ setbit(out[y/8], 7-(y%8));
+ }
if ((y & 7) == 7) {
++x;
}
diff --git a/libtomcrypt/pk/asn1/der/bit/der_encode_bit_string.c b/libtomcrypt/pk/asn1/der/bit/der_encode_bit_string.c
index d77ea5a..d1b6064 100644
--- a/libtomcrypt/pk/asn1/der/bit/der_encode_bit_string.c
+++ b/libtomcrypt/pk/asn1/der/bit/der_encode_bit_string.c
@@ -18,9 +18,11 @@
#ifdef LTC_DER
+#define getbit(n, k) (((n) & ( 1 << (k) )) >> (k))
+
/**
Store a BIT STRING
- @param in The array of bits to store (one per char)
+ @param in The array of bits to store (8 per char)
@param inlen The number of bits tostore
@param out [out] The destination for the DER encoded BIT STRING
@param outlen [in/out] The max size and resulting size of the DER BIT STRING
@@ -68,7 +70,7 @@ int der_encode_bit_string(const unsigned char *in, unsigned long inlen,
/* store the bits in big endian format */
for (y = buf = 0; y < inlen; y++) {
- buf |= (in[y] ? 1 : 0) << (7 - (y & 7));
+ buf |= (getbit(in[y/8],7-y%8)?1:0) << (7 - (y & 7));
if ((y & 7) == 7) {
out[x++] = buf;
buf = 0;
@@ -78,6 +80,7 @@ int der_encode_bit_string(const unsigned char *in, unsigned long inlen,
if (inlen & 7) {
out[x++] = buf;
}
+
*outlen = x;
return CRYPT_OK;
}
diff --git a/libtomcrypt/pk/asn1/der/sequence/der_decode_subject_public_key_info.c b/libtomcrypt/pk/asn1/der/sequence/der_decode_subject_public_key_info.c
new file mode 100644
index 0000000..6c97e96
--- /dev/null
+++ b/libtomcrypt/pk/asn1/der/sequence/der_decode_subject_public_key_info.c
@@ -0,0 +1,97 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ */
+#include "tomcrypt.h"
+/**
+ @file der_encode_sequence_multi.c
+ ASN.1 DER, encode a Subject Public Key structure --nmav
+*/
+
+#ifdef LTC_DER
+
+/* AlgorithmIdentifier := SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm
+ * }
+ *
+ * SubjectPublicKeyInfo := SEQUENCE {
+ * algorithm AlgorithmIdentifier,
+ * subjectPublicKey BIT STRING
+ * }
+ */
+/**
+ Encode a SEQUENCE type using a VA list
+ @param out [out] Destination for data
+ @param outlen [in/out] Length of buffer and resulting length of output
+ @remark <...> is of the form <type, size, data> (int, unsigned long, void*)
+ @return CRYPT_OK on success
+*/
+int der_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen,
+ unsigned int algorithm, void* public_key, unsigned long* public_key_len,
+ unsigned long parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len)
+{
+ int err, len;
+ oid_st oid;
+ unsigned char *tmpbuf;
+ unsigned long tmpoid[16];
+ ltc_asn1_list alg_id[2];
+ ltc_asn1_list subject_pubkey[2];
+
+ LTC_ARGCHK(in != NULL);
+ LTC_ARGCHK(inlen != 0);
+
+ err = pk_get_oid(algorithm, &oid);
+ if (err != CRYPT_OK) {
+ return err;
+ }
+
+ /* see if the OpenSSL DER format RSA public key will work */
+ tmpbuf = XCALLOC(1, MAX_RSA_SIZE*8);
+ if (tmpbuf == NULL) {
+ err = CRYPT_MEM;
+ goto LBL_ERR;
+ }
+
+ /* this includes the internal hash ID and optional params (NULL in this case) */
+ LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0]));
+ LTC_SET_ASN1(alg_id, 1, parameters_type, parameters, parameters_len);
+
+ /* the actual format of the SSL DER key is odd, it stores a RSAPublicKey in a **BIT** string ... so we have to extract it
+ then proceed to convert bit to octet
+ */
+ LTC_SET_ASN1(subject_pubkey, 0, LTC_ASN1_SEQUENCE, alg_id, 2);
+ LTC_SET_ASN1(subject_pubkey, 1, LTC_ASN1_BIT_STRING, tmpbuf, MAX_RSA_SIZE*8);
+
+ err=der_decode_sequence(in, inlen, subject_pubkey, 2UL);
+ if (err != CRYPT_OK) {
+ goto LBL_ERR;
+ }
+
+ len = subject_pubkey[1].size/8;
+ if (*public_key_len > len) {
+ memcpy(public_key, subject_pubkey[1].data, len);
+ *public_key_len = len;
+ } else {
+ *public_key_len = len;
+ err = CRYPT_BUFFER_OVERFLOW;
+ goto LBL_ERR;
+ }
+
+ err = CRYPT_OK;
+
+LBL_ERR:
+
+ XFREE(tmpbuf);
+
+ return err;
+}
+
+#endif
+
+
diff --git a/libtomcrypt/pk/asn1/der/sequence/der_encode_subject_public_key_info.c b/libtomcrypt/pk/asn1/der/sequence/der_encode_subject_public_key_info.c
new file mode 100644
index 0000000..e37c4b4
--- /dev/null
+++ b/libtomcrypt/pk/asn1/der/sequence/der_encode_subject_public_key_info.c
@@ -0,0 +1,69 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ */
+#include "tomcrypt.h"
+
+/**
+ @file der_encode_sequence_multi.c
+ ASN.1 DER, encode a Subject Public Key structure --nmav
+*/
+
+#ifdef LTC_DER
+
+/* AlgorithmIdentifier := SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm
+ * }
+ *
+ * SubjectPublicKeyInfo := SEQUENCE {
+ * algorithm AlgorithmIdentifier,
+ * subjectPublicKey BIT STRING
+ * }
+ */
+/**
+ Encode a SEQUENCE type using a VA list
+ @param out [out] Destination for data
+ @param outlen [in/out] Length of buffer and resulting length of output
+ @remark <...> is of the form <type, size, data> (int, unsigned long, void*)
+ @return CRYPT_OK on success
+*/
+int der_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen,
+ unsigned int algorithm, void* public_key, unsigned long public_key_len,
+ unsigned long parameters_type, void* parameters, unsigned long parameters_len)
+{
+ int err;
+ ltc_asn1_list alg_id[2];
+ oid_st oid;
+
+ LTC_ARGCHK(out != NULL);
+ LTC_ARGCHK(outlen != NULL);
+
+ err = pk_get_oid(algorithm, &oid);
+ if (err != CRYPT_OK) {
+ return err;
+ }
+
+ alg_id[0].data = oid.OID;
+ alg_id[0].size = oid.OIDlen;
+ alg_id[0].type = LTC_ASN1_OBJECT_IDENTIFIER;
+
+ alg_id[1].data = parameters;
+ alg_id[1].size = parameters_len;
+ alg_id[1].type = parameters_type;
+
+ return der_encode_sequence_multi(out, outlen,
+ LTC_ASN1_SEQUENCE, (unsigned long)sizeof(alg_id)/sizeof(alg_id[0]), alg_id,
+ LTC_ASN1_BIT_STRING, (unsigned long)(public_key_len*8), public_key,
+ LTC_ASN1_EOL, 0UL, NULL);
+
+}
+
+#endif
+
+
diff --git a/libtomcrypt/pk/dsa/dsa_export.c b/libtomcrypt/pk/dsa/dsa_export.c
index 11b6638..1fef6c7 100644
--- a/libtomcrypt/pk/dsa/dsa_export.c
+++ b/libtomcrypt/pk/dsa/dsa_export.c
@@ -27,8 +27,8 @@
*/
int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key)
{
- unsigned char flags[1];
unsigned long zero=0;
+ int err;
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
@@ -43,8 +43,6 @@ int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key
return CRYPT_INVALID_ARG;
}
- flags[0] = (type != PK_PUBLIC) ? 1 : 0;
-
/* This encoding is different from the one in original
* libtomcrypt. It uses a compatible encoding with gnutls
* and openssl
@@ -59,13 +57,36 @@ int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key
LTC_ASN1_INTEGER, 1UL, &key->x,
LTC_ASN1_EOL, 0UL, NULL);
} else {
- return der_encode_sequence_multi(out, outlen,
- LTC_ASN1_BIT_STRING, 1UL, flags,
- LTC_ASN1_INTEGER, 1UL, &key->g,
- LTC_ASN1_INTEGER, 1UL, &key->p,
- LTC_ASN1_INTEGER, 1UL, &key->q,
- LTC_ASN1_INTEGER, 1UL, &key->y,
- LTC_ASN1_EOL, 0UL, NULL);
+ unsigned long tmplen = (mp_count_bits(&key->y)/8)+8;
+ unsigned char* tmp = XMALLOC(tmplen);
+ ltc_asn1_list int_list[3];
+
+ if (tmp == NULL) {
+ return CRYPT_MEM;
+ }
+
+ err = der_encode_integer(&key->y, tmp, &tmplen);
+ if (err != CRYPT_OK) {
+ goto error;
+ }
+
+ int_list[0].data = &key->p;
+ int_list[0].size = 1UL;
+ int_list[0].type = LTC_ASN1_INTEGER;
+ int_list[1].data = &key->q;
+ int_list[1].size = 1UL;
+ int_list[1].type = LTC_ASN1_INTEGER;
+ int_list[2].data = &key->g;
+ int_list[2].size = 1UL;
+ int_list[2].type = LTC_ASN1_INTEGER;
+
+ err = der_encode_subject_public_key_info(out, outlen,
+ PKA_DSA, tmp, tmplen,
+ LTC_ASN1_SEQUENCE, int_list, sizeof(int_list)/sizeof(int_list[0]));
+
+error:
+ XFREE(tmp);
+ return err;
}
}
diff --git a/libtomcrypt/pk/dsa/dsa_import.c b/libtomcrypt/pk/dsa/dsa_import.c
index 88e74f5..c0680f5 100644
--- a/libtomcrypt/pk/dsa/dsa_import.c
+++ b/libtomcrypt/pk/dsa/dsa_import.c
@@ -26,9 +26,9 @@
*/
int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
{
- unsigned char flags[1];
int err;
unsigned long zero = 0;
+ unsigned char* tmpbuf = NULL;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(key != NULL);
@@ -40,44 +40,55 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
/* get key type */
if ((err = der_decode_sequence_multi(in, inlen,
- LTC_ASN1_BIT_STRING, 1UL, flags,
- LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
- /* private key */
- if ((err = der_decode_sequence_multi(in, inlen,
LTC_ASN1_SHORT_INTEGER, 1UL, &zero,
LTC_ASN1_INTEGER, 1UL, &key->p,
LTC_ASN1_INTEGER, 1UL, &key->q,
LTC_ASN1_INTEGER, 1UL, &key->g,
LTC_ASN1_INTEGER, 1UL, &key->y,
LTC_ASN1_INTEGER, 1UL, &key->x,
- LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
- goto error;
- }
+ LTC_ASN1_EOL, 0UL, NULL)) == CRYPT_OK) {
key->type = PK_PRIVATE;
-
} else { /* public */
+ ltc_asn1_list params[3];
+ unsigned long tmpbuf_len = MAX_RSA_SIZE*8;
+
+ LTC_SET_ASN1(params, 0, LTC_ASN1_INTEGER, &key->p, 1UL);
+ LTC_SET_ASN1(params, 1, LTC_ASN1_INTEGER, &key->q, 1UL);
+ LTC_SET_ASN1(params, 2, LTC_ASN1_INTEGER, &key->g, 1UL);
+
+ tmpbuf = XCALLOC(1, tmpbuf_len);
+ if (tmpbuf == NULL) {
+ err = CRYPT_MEM;
+ goto LBL_ERR;
+ }
- if ((err = der_decode_sequence_multi(in, inlen,
- LTC_ASN1_BIT_STRING, 1UL, flags,
- LTC_ASN1_INTEGER, 1UL, &key->g,
- LTC_ASN1_INTEGER, 1UL, &key->p,
- LTC_ASN1_INTEGER, 1UL, &key->q,
- LTC_ASN1_INTEGER, 1UL, &key->y,
- LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
- goto error;
+ err = der_decode_subject_public_key_info(in, inlen,
+ PKA_DSA, tmpbuf, &tmpbuf_len,
+ LTC_ASN1_SEQUENCE, params, 3);
+ if (err != CRYPT_OK) {
+ goto LBL_ERR;
}
+
+ if ((err=der_decode_integer(tmpbuf, tmpbuf_len, &key->y)) != CRYPT_OK) {
+ goto LBL_ERR;
+ }
+
+ XFREE(tmpbuf);
key->type = PK_PUBLIC;
}
+
key->qord = mp_unsigned_bin_size(&key->q);
if (key->qord >= LTC_MDSA_MAX_GROUP || key->qord <= 15 ||
(unsigned long)key->qord >= mp_unsigned_bin_size(&key->p) || (mp_unsigned_bin_size(&key->p) - key->qord) >= LTC_MDSA_DELTA) {
err = CRYPT_INVALID_PACKET;
- goto error;
+ goto LBL_ERR;
}
return CRYPT_OK;
-error:
+
+LBL_ERR:
+ XFREE(tmpbuf);
mp_clear_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL);
return err;
}
diff --git a/libtomcrypt/pk/rsa/rsa_export.c b/libtomcrypt/pk/rsa/rsa_export.c
index 04e59d8..33c222d 100644
--- a/libtomcrypt/pk/rsa/rsa_export.c
+++ b/libtomcrypt/pk/rsa/rsa_export.c
@@ -9,7 +9,7 @@
* Tom St Denis, tomstdenis@gmail.com, http://libtom.org
*/
#include "tomcrypt.h"
-
+#include <ncr_int.h>
/**
@file rsa_export.c
Export RSA LTC_PKCS keys, Tom St Denis
@@ -28,6 +28,7 @@
int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key)
{
unsigned long zero=0;
+ int err;
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
LTC_ARGCHK(key != NULL);
@@ -54,11 +55,27 @@ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key
LTC_ASN1_INTEGER, 1UL, &key->qP,
LTC_ASN1_EOL, 0UL, NULL);
} else {
- /* public key */
- return der_encode_sequence_multi(out, outlen,
+ unsigned long tmplen = (mp_count_bits(&key->N)/8)*2+8;
+ unsigned char* tmp = XMALLOC(tmplen);
+
+ if (tmp == NULL) {
+ return CRYPT_MEM;
+ }
+
+ err = der_encode_sequence_multi(tmp, &tmplen,
LTC_ASN1_INTEGER, 1UL, &key->N,
LTC_ASN1_INTEGER, 1UL, &key->e,
LTC_ASN1_EOL, 0UL, NULL);
+ if (err != CRYPT_OK) {
+ goto error;
+ }
+
+ err = der_encode_subject_public_key_info(out, outlen,
+ PKA_RSA, tmp, tmplen, LTC_ASN1_NULL, NULL, 0);
+
+error:
+ XFREE(tmp);
+ return err;
}
}
diff --git a/libtomcrypt/pk/rsa/rsa_import.c b/libtomcrypt/pk/rsa/rsa_import.c
index db78236..2eaa0a9 100644
--- a/libtomcrypt/pk/rsa/rsa_import.c
+++ b/libtomcrypt/pk/rsa/rsa_import.c
@@ -28,10 +28,8 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
{
int err;
mp_int zero;
- unsigned char *tmpbuf;
- unsigned long t, x, y, z, tmpoid[16];
- ltc_asn1_list ssl_pubkey_hashoid[2];
- ltc_asn1_list ssl_pubkey[2];
+ unsigned char *tmpbuf=NULL;
+ unsigned long tmpbuf_len;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(key != NULL);
@@ -43,47 +41,33 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
}
/* see if the OpenSSL DER format RSA public key will work */
- tmpbuf = XCALLOC(1, MAX_RSA_SIZE*8);
+ tmpbuf_len = MAX_RSA_SIZE * 8;
+ tmpbuf = XCALLOC(1, tmpbuf_len);
if (tmpbuf == NULL) {
err = CRYPT_MEM;
goto LBL_ERR;
}
- /* this includes the internal hash ID and optional params (NULL in this case) */
- LTC_SET_ASN1(ssl_pubkey_hashoid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0]));
- LTC_SET_ASN1(ssl_pubkey_hashoid, 1, LTC_ASN1_NULL, NULL, 0);
-
- /* the actual format of the SSL DER key is odd, it stores a RSAPublicKey in a **BIT** string ... so we have to extract it
- then proceed to convert bit to octet
- */
- LTC_SET_ASN1(ssl_pubkey, 0, LTC_ASN1_SEQUENCE, &ssl_pubkey_hashoid, 2);
- LTC_SET_ASN1(ssl_pubkey, 1, LTC_ASN1_BIT_STRING, tmpbuf, MAX_RSA_SIZE*8);
-
- if (der_decode_sequence(in, inlen,
- ssl_pubkey, 2UL) == CRYPT_OK) {
-
- /* ok now we have to reassemble the BIT STRING to an OCTET STRING. Thanks OpenSSL... */
- for (t = y = z = x = 0; x < ssl_pubkey[1].size; x++) {
- y = (y << 1) | tmpbuf[x];
- if (++z == 8) {
- tmpbuf[t++] = (unsigned char)y;
- y = 0;
- z = 0;
- }
- }
+ err = der_decode_subject_public_key_info(in, inlen,
+ PKA_RSA, tmpbuf, &tmpbuf_len,
+ LTC_ASN1_NULL, NULL, 0);
+
+ if (err == CRYPT_OK) { /* SubjectPublicKeyInfo format */
/* now it should be SEQUENCE { INTEGER, INTEGER } */
- if ((err = der_decode_sequence_multi(tmpbuf, t,
+ if ((err = der_decode_sequence_multi(tmpbuf, tmpbuf_len,
LTC_ASN1_INTEGER, 1UL, &key->N,
LTC_ASN1_INTEGER, 1UL, &key->e,
LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
- XFREE(tmpbuf);
goto LBL_ERR;
}
+
XFREE(tmpbuf);
+
key->type = PK_PUBLIC;
return CRYPT_OK;
}
+
XFREE(tmpbuf);
/* not SSL public key, try to match against LTC_PKCS #1 standards */
@@ -130,6 +114,7 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
}
return CRYPT_OK;
LBL_ERR:
+ XFREE(tmpbuf);
mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL);
return err;
}